From ddc482e30665eda2b5bf7f5b7b73b533e2d7103c Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 12 Feb 2020 15:11:07 -0500 Subject: [PATCH 01/42] Update tests to match removal of Synapse sending events when creating or deleting aliases. --- .gitignore | 3 +- tests/30rooms/05aliases.pl | 99 ----------------------------- tests/60app-services/01as-create.pl | 45 ++----------- tests/60app-services/03passive.pl | 21 ------ tests/61push/01message-pushed.pl | 36 +++-------- 5 files changed, 17 insertions(+), 187 deletions(-) diff --git a/.gitignore b/.gitignore index 9053061b3..07194712c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ /var \#* .vscode -.coverage* \ No newline at end of file +.coverage* +.idea diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index 5cc46d70b..6fb63e0af 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -177,20 +177,6 @@ sub _test_can_create_and_delete_alias { content => { room_id => $room_id }, )->then( sub { - matrix_get_room_state( $user, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - log_if_fail "Aliases after adding alias", $body; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - any { $_ eq $alias } @$aliases or die "Expected alias to be in list"; - do_request_json_for( $user, method => "DELETE", uri => "/r0/directory/room/$alias", @@ -198,19 +184,6 @@ sub _test_can_create_and_delete_alias { content => {}, ) })->then( sub { - matrix_get_room_state( $user, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - log_if_fail "Aliases after deleting alias", $body; - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - none { $_ eq $alias } @$aliases or die "Expected alias to not be in list"; - Future->done; }); } @@ -278,18 +251,6 @@ sub _test_can_create_and_delete_alias { content => { alias => $room_alias } ) })->then( sub { - matrix_get_room_state( $creator, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - any { $_ eq $room_alias } @$aliases or die "Expected alias to be in list"; - do_request_json_for( $creator, method => "DELETE", uri => "/r0/directory/room/$room_alias", @@ -297,18 +258,6 @@ sub _test_can_create_and_delete_alias { content => {}, ) })->then( sub { - matrix_get_room_state( $creator, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - none { $_ eq $room_alias } @$aliases or die "Expected alias to not be in list"; - matrix_get_room_state( $creator, $room_id, type => "m.room.canonical_alias", ) @@ -340,18 +289,6 @@ sub _test_can_create_and_delete_alias { content => { room_id => $room_id }, ) })->then( sub { - matrix_get_room_state( $creator, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - any { $_ eq $room_alias } @$aliases or die "Expected alias to be in list"; - do_request_json_for( $other_user, method => "DELETE", uri => "/r0/directory/room/$room_alias", @@ -359,18 +296,6 @@ sub _test_can_create_and_delete_alias { content => {}, ) })->then( sub { - matrix_get_room_state( $creator, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - none { $_ eq $room_alias } @$aliases or die "Expected alias to not be in list"; - Future->done(1); }) }; @@ -399,18 +324,6 @@ sub _test_can_create_and_delete_alias { content => { alias => $room_alias } ) })->then( sub { - matrix_get_room_state( $creator, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - any { $_ eq $room_alias } @$aliases or die "Expected alias to be in list"; - do_request_json_for( $other_user, method => "DELETE", uri => "/r0/directory/room/$room_alias", @@ -418,18 +331,6 @@ sub _test_can_create_and_delete_alias { content => {}, ) })->then( sub { - matrix_get_room_state( $creator, $room_id, - type => "m.room.aliases", - state_key => $server_name, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( aliases ) ); - assert_json_list( my $aliases = $body->{aliases} ); - - none { $_ eq $room_alias } @$aliases or die "Expected alias to not be in list"; - Future->done(1); }) }; diff --git a/tests/60app-services/01as-create.pl b/tests/60app-services/01as-create.pl index 39df7c49f..973ad5306 100644 --- a/tests/60app-services/01as-create.pl +++ b/tests/60app-services/01as-create.pl @@ -115,46 +115,13 @@ do => sub { my ( $as_user, $appserv, $room_id, $room_alias ) = @_; - Future->needs_all( - $appserv->await_event( "m.room.aliases" )->then( sub { - my ( $event, $request ) = @_; - - # As this is the first AS event we've received, lets check that the - # token matches, to give that coverage. - - my $access_token = $request->query_param( "access_token" ); - - assert_ok( defined $access_token, - "HS provides an access_token" ); - assert_eq( $access_token, $appserv->info->hs2as_token, - "HS provides the correct token" ); - - log_if_fail "Event", $event; - - assert_json_keys( $event, qw( content room_id user_id )); - - $event->{room_id} eq $room_id or - die "Expected room_id to be $room_id"; - $event->{user_id} eq $as_user->user_id or - die "Expected user_id to be ${\$as_user->user_id}"; - - assert_json_keys( my $content = $event->{content}, qw( aliases )); - assert_json_list( my $aliases = $content->{aliases} ); - - grep { $_ eq $room_alias } @$aliases or - die "Expected to find our alias in the aliases list"; - - Future->done; - }), - - do_request_json_for( $as_user, - method => "PUT", - uri => "/r0/directory/room/$room_alias", + do_request_json_for( $as_user, + method => "PUT", + uri => "/r0/directory/room/$room_alias", - content => { - room_id => $room_id, - }, - ) + content => { + room_id => $room_id, + }, )->then( sub { # Nothing interesting in the body diff --git a/tests/60app-services/03passive.pl b/tests/60app-services/03passive.pl index d7f126c1a..98e0bf94e 100644 --- a/tests/60app-services/03passive.pl +++ b/tests/60app-services/03passive.pl @@ -89,27 +89,6 @@ Future->done; }), - $appserv->await_event( "m.room.aliases" )->then( sub { - my ( $event ) = @_; - - log_if_fail "Event", $event; - - assert_json_keys( $event, qw( content room_id user_id )); - - $event->{room_id} eq $room_id or - die "Expected room_id to be $room_id"; - $event->{user_id} eq $as_user->user_id or - die "Expected user_id to be ${\$as_user->user_id}"; - - assert_json_keys( my $content = $event->{content}, qw( aliases )); - assert_json_list( my $aliases = $content->{aliases} ); - - grep { $_ eq $room_alias } @$aliases or - die "Expected to find our alias in the aliases list"; - - Future->done; - }), - do_request_json_for( $local_user, method => "POST", uri => "/r0/join/$room_alias", diff --git a/tests/61push/01message-pushed.pl b/tests/61push/01message-pushed.pl index e5800b121..daf389689 100644 --- a/tests/61push/01message-pushed.pl +++ b/tests/61push/01message-pushed.pl @@ -280,31 +280,6 @@ sub check_received_push_with_name }); } -test "Rooms with aliases are correctly named in pushed", - requires => [ - local_user_fixtures( 2, with_events => 0 ), room_alias_fixture(), - $main::TEST_SERVER_INFO - ], - - check => sub { - my ( $alice, $bob, $room_alias, $test_server_info ) = @_; - my $room_id; - - setup_push( $alice, $bob, $test_server_info, "/alice_push" ) - ->then( sub { - ( $room_id ) = @_; - - do_request_json_for( $bob, - method => "PUT", - uri => "/r0/directory/room/$room_alias", - - content => { room_id => $room_id }, - ) - })->then( sub { - check_received_push_with_name( $bob, $room_id, "/alice_push", $room_alias ) - }); - }; - test "Rooms with names are correctly named in pushed", requires => [ local_user_fixtures( 2, with_events => 0 ), @@ -370,10 +345,17 @@ sub check_received_push_with_name my ( $alice, $bob, $charlie, $room_alias, $test_server_info ) = @_; my $room_id; + my $name = "Test Name"; + setup_push( $alice, $bob, $test_server_info, "/alice_push" ) ->then( sub { - ( $room_id ) = @_; + ($room_id) = @_; + matrix_put_room_state($bob, $room_id, + type => "m.room.name", + content => { name => $name }, + ); + })->then( sub { matrix_join_room( $charlie, $room_id) })->then( sub { do_request_json_for( $bob, @@ -383,7 +365,7 @@ sub check_received_push_with_name content => { room_id => $room_id }, ) })->then( sub { - check_received_push_with_name( $bob, $room_id, "/alice_push", $room_alias ) + check_received_push_with_name( $bob, $room_id, "/alice_push", $name ) }); }; From dfb664d448fb07f9f7f9902d9dbe0a6089e02087 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 17 Feb 2020 10:02:26 +0000 Subject: [PATCH 02/42] Test /user/devices/ on fed reader (#799) --- lib/SyTest/Homeserver/Synapse.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/SyTest/Homeserver/Synapse.pm b/lib/SyTest/Homeserver/Synapse.pm index 022580f72..db24869e9 100644 --- a/lib/SyTest/Homeserver/Synapse.pm +++ b/lib/SyTest/Homeserver/Synapse.pm @@ -1183,6 +1183,7 @@ sub generate_haproxy_map ^/_matrix/federation/v1/exchange_third_party_invite/ federation_reader ^/_matrix/federation/v1/send/ federation_reader ^/_matrix/federation/v1/get_groups_publicised federation_reader +^/_matrix/federation/v1/user/devices/ federation_reader ^/_matrix/key/v2/query federation_reader ^/_matrix/client/(api/v1|r0|unstable)/publicRooms$ client_reader From eef452827a5abab09b4be8f56efbb25ba30f4d19 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Mon, 17 Feb 2020 13:37:37 +0000 Subject: [PATCH 03/42] Support running dendrite in sqlite --- lib/SyTest/Homeserver/Dendrite.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/SyTest/Homeserver/Dendrite.pm b/lib/SyTest/Homeserver/Dendrite.pm index 210298410..dc18f1a63 100644 --- a/lib/SyTest/Homeserver/Dendrite.pm +++ b/lib/SyTest/Homeserver/Dendrite.pm @@ -102,6 +102,12 @@ sub _get_config $db_uri .= sprintf( " sslmode=%s", $db_config{args}->{sslmode} ); } + # POSTGRES not set or is 0, use sqlite + if( ! defined $ENV{'POSTGRES'} || $ENV{'POSTGRES'} == '0') { + print STDERR "\nUsing sqlite database\n"; + $db_uri = "file:dendrite.db"; + } + return ( version => 0, matrix => { From ac23101b2ef767038dcc94af27941d374220d766 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 18 Feb 2020 11:30:30 +0000 Subject: [PATCH 04/42] Update tests that assumed PL50 for room upgrade, fix others (#805) --- tests/30rooms/12thirdpartyinvite.pl | 29 ++++++++++++++++------ tests/30rooms/60version_upgrade.pl | 22 +++++----------- tests/41end-to-end-keys/06-device-lists.pl | 2 ++ 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/tests/30rooms/12thirdpartyinvite.pl b/tests/30rooms/12thirdpartyinvite.pl index 1384453a0..cbaa0c4c0 100644 --- a/tests/30rooms/12thirdpartyinvite.pl +++ b/tests/30rooms/12thirdpartyinvite.pl @@ -44,7 +44,7 @@ }); }; -test "Can invite existing 3pid with no ops", +test "Can invite existing 3pid with no ops into a private room", requires => [ local_user_fixtures( 3 ), id_server_fixture() ], do => sub { @@ -57,7 +57,12 @@ $id_server->bind_identity( undef, "email", $invitee_email, $invitee ) ->then( sub { - matrix_create_and_join_room( [ $creator, $inviter ], visibility => "private", with_invite => 1 ) + matrix_create_and_join_room( + [ $creator, $inviter ], + visibility => "private", + preset => "private_chat", # Allow default PL users to invite others + with_invite => 1, + ) })->then( sub { ( $room_id ) = @_; @@ -155,7 +160,7 @@ }); }; -test "Can invite unbound 3pid with no ops", +test "Can invite unbound 3pid with no ops into a private room", requires => [ local_user_fixtures( 3 ), $main::HOMESERVER_INFO[0], id_server_fixture() ], @@ -163,14 +168,18 @@ my ( $creator, $inviter, $invitee, $info, $id_server ) = @_; my $hs_uribase = $info->client_location; - matrix_create_and_join_room( [ $creator, $inviter ], visibility => "private", with_invite => 1 ) - ->then( sub { + matrix_create_and_join_room( + [ $creator, $inviter ], + visibility => "private", + preset => "private_chat", # Allow default PL users to invite others + with_invite => 1, + )->then( sub { my ( $room_id ) = @_; can_invite_unbound_3pid( $room_id, $inviter, $invitee, $hs_uribase, $id_server ); }); }; -test "Can invite unbound 3pid over federation with no ops", +test "Can invite unbound 3pid over federation with no ops into a private room", requires => [ local_user_fixtures( 2 ), remote_user_fixture(), $main::HOMESERVER_INFO[1], id_server_fixture() ], @@ -178,8 +187,12 @@ my ( $creator, $inviter, $invitee, $info, $id_server ) = @_; my $hs_uribase = $info->client_location; - matrix_create_and_join_room( [ $creator, $inviter ], visibility => "private", with_invite => 1 ) - ->then( sub { + matrix_create_and_join_room( + [ $creator, $inviter ], + visibility => "private", + preset => "private_chat", + with_invite => 1, + )->then( sub { my ( $room_id ) = @_; can_invite_unbound_3pid( $room_id, $inviter, $invitee, $hs_uribase, $id_server ); }); diff --git a/tests/30rooms/60version_upgrade.pl b/tests/30rooms/60version_upgrade.pl index 0f1c8e0f5..4e847e5c2 100644 --- a/tests/30rooms/60version_upgrade.pl +++ b/tests/30rooms/60version_upgrade.pl @@ -374,6 +374,7 @@ sub upgrade_room_synced { }); }; +# See https://github.com/matrix-org/synapse/issues/6632 for details test "/upgrade preserves the power level of the upgrading user in old and new rooms", requires => [ local_user_and_room_fixtures(), @@ -386,8 +387,6 @@ sub upgrade_room_synced { my ( $pl_content, $new_room_id ); - # Note that this test assumes that moderators by default are allowed to upgrade rooms - matrix_join_room_synced( $upgrader, $room_id )->then( sub { @@ -396,6 +395,11 @@ sub upgrade_room_synced { $creator, $room_id, sub { ( $pl_content ) = @_; $pl_content->{users}->{$upgrader->user_id} = JSON::number(50); + + # Note that this test assumes that moderators by default are allowed to upgrade rooms + # Change the PL rules to allow moderators to send tombstones + $pl_content->{events}->{"m.room.tombstone"} = JSON::number(50); + log_if_fail "PL content in old room", $pl_content; } ) @@ -501,19 +505,6 @@ sub upgrade_room_synced { } $f->then( sub { - # to make things harder, we now restrict our ability to change each of - # those states: the server should make sure it sets up the state - # *before* it replicates the PL. - matrix_change_room_power_levels( - $creator, $room_id, sub { - my ( $levels ) = @_; - foreach my $k ( keys %STATE_DICT ) { - $levels->{events}->{$k} = 80; - } - $levels->{users}->{$creator->user_id} = 50; - }, - ); - })->then( sub { matrix_sync( $creator ); })->then( sub { upgrade_room_synced( @@ -547,7 +538,6 @@ sub upgrade_room_synced { }); }; - test "/upgrade copies ban events to the new room", requires => [ local_user_and_room_fixtures(), diff --git a/tests/41end-to-end-keys/06-device-lists.pl b/tests/41end-to-end-keys/06-device-lists.pl index 089d395d7..f2da9fb90 100644 --- a/tests/41end-to-end-keys/06-device-lists.pl +++ b/tests/41end-to-end-keys/06-device-lists.pl @@ -689,6 +689,8 @@ sub sync_until_user_in_device_list matrix_create_room( $creator, invite => [ $remote_user->user_id ], + # Allow default PL users to invite others + preset => "private_chat", )->then( sub { ( $room_id ) = @_; From 97fbd25805534bb0758b931866ffed9e6df9d33c Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 18 Feb 2020 16:16:22 +0000 Subject: [PATCH 05/42] Route /publicised_groups/ to client reader (#807) --- lib/SyTest/Homeserver/Synapse.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/SyTest/Homeserver/Synapse.pm b/lib/SyTest/Homeserver/Synapse.pm index db24869e9..015731bd3 100644 --- a/lib/SyTest/Homeserver/Synapse.pm +++ b/lib/SyTest/Homeserver/Synapse.pm @@ -1201,6 +1201,8 @@ sub generate_haproxy_map ^/_matrix/client/(api/v1|r0|unstable)/rooms/.*/messages$ client_reader ^/_matrix/client/(api/v1|r0|unstable)/get_groups_publicised$ client_reader ^/_matrix/client/(api/v1|r0|unstable)/joined_groups$ client_reader +^/_matrix/client/(api/v1|r0|unstable)/publicised_groups$ client_reader +^/_matrix/client/(api/v1|r0|unstable)/publicised_groups/ client_reader ^/_matrix/client/(api/v1|r0|unstable)/keys/upload frontend_proxy From 37cbb36566a94a7ebcc14482c2c811063d642b2d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 18 Feb 2020 16:23:46 +0000 Subject: [PATCH 06/42] Tests for /rooms/:room_id/aliases (#809) cf matrix-org/synapse#6939 --- lib/SyTest/HTTPClient.pm | 2 ++ tests/10apidoc/00prepare.pl | 2 ++ tests/10apidoc/02login.pl | 1 + tests/10apidoc/32room-alias.pl | 47 ++++++++++++++++++++++++++++++++++ tests/12login/02cas.pl | 2 ++ tests/30rooms/05aliases.pl | 32 +++++++++++++++++++++++ 6 files changed, 86 insertions(+) diff --git a/lib/SyTest/HTTPClient.pm b/lib/SyTest/HTTPClient.pm index cd3fa37ef..519e2c92c 100644 --- a/lib/SyTest/HTTPClient.pm +++ b/lib/SyTest/HTTPClient.pm @@ -83,6 +83,8 @@ sub do_request my $self = shift; my %params = @_; + croak "must give a method" unless $params{method}; + my $uri = $self->full_uri_for( %params ); # Also set verify_mode = 0 to not complain about self-signed SSL certs diff --git a/tests/10apidoc/00prepare.pl b/tests/10apidoc/00prepare.pl index 5642cd0b7..fe1266626 100644 --- a/tests/10apidoc/00prepare.pl +++ b/tests/10apidoc/00prepare.pl @@ -13,6 +13,8 @@ sub do_request_json_for my ( $user, %args ) = @_; is_User( $user ) or croak "Expected a User"; + croak "must give a method" unless $args{method}; + my $user_id = $user->user_id; ( my $uri = delete $args{uri} ) =~ s/:user_id/$user_id/g; diff --git a/tests/10apidoc/02login.pl b/tests/10apidoc/02login.pl index 2e0b1f093..2c9dc9c6f 100644 --- a/tests/10apidoc/02login.pl +++ b/tests/10apidoc/02login.pl @@ -37,6 +37,7 @@ my ( $http ) = @_; $http->do_request_json( + method => "GET", uri => "/r0/login", )->then( sub { my ( $body ) = @_; diff --git a/tests/10apidoc/32room-alias.pl b/tests/10apidoc/32room-alias.pl index b28cc755f..9ffe20146 100644 --- a/tests/10apidoc/32room-alias.pl +++ b/tests/10apidoc/32room-alias.pl @@ -48,3 +48,50 @@ Future->done(1); }); }; + +test "GET /rooms/:room_id/aliases lists aliases", + requires => [ $user_fixture, room_alias_fixture(), qw( can_create_room_alias )], + + do => sub { + my ( $user, $room_alias ) = @_; + my ( $room_id ); + + matrix_create_room( $user )->then( sub { + ( $room_id ) = @_; + + # the list should be empty initially + do_request_json_for( + $user, + method => "GET", + uri => "/r0/rooms/$room_id/aliases", + ); + })->then( sub { + my ( $res ) = @_; + log_if_fail "response from /aliases", $res; + + assert_json_keys( $res, qw( aliases )); + assert_json_empty_list( $res->{aliases} ); + + # now add an alias + do_request_json_for( + $user, + method => "PUT", + uri => "/r0/directory/room/$room_alias", + content => { room_id => $room_id }, + ); + })->then( sub { + # ... and recheck + do_request_json_for( + $user, + method => "GET", + uri => "/r0/rooms/$room_id/aliases", + ); + })->then( sub { + my ( $res ) = @_; + log_if_fail "response from /aliases", $res; + + assert_json_keys( $res, qw( aliases )); + assert_deeply_eq($res->{aliases}, [ $room_alias ]); + Future->done; + }); + }; diff --git a/tests/12login/02cas.pl b/tests/12login/02cas.pl index bcda55305..854b4956a 100644 --- a/tests/12login/02cas.pl +++ b/tests/12login/02cas.pl @@ -33,6 +33,7 @@ sub wait_for_cas_request my ( $http ) = @_; $http->do_request_json( + method => "GET", uri => "/r0/login", )->then( sub { my ( $body ) = @_; @@ -55,6 +56,7 @@ sub wait_for_cas_request my ( $http ) = @_; $http->do_request_json( + method => "GET", uri => "/r0/login", )->then( sub { my ( $body ) = @_; diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index 6fb63e0af..705e995a3 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -334,3 +334,35 @@ sub _test_can_create_and_delete_alias { Future->done(1); }) }; + + +test "Only room members can list aliases of a room", + requires => [ + $creator_fixture, $second_user_fixture, local_user_fixture(), + ], + + do => sub { + my ( $creator, $other_user, $third_user ) = @_; + my ( $room_id ); + + matrix_create_and_join_room( + [ $creator, $other_user ], + )->then( sub { + ( $room_id ) = @_; + do_request_json_for( + $other_user, + method => "GET", + uri => "/r0/rooms/$room_id/aliases", + ); + })->then( sub { + my ( $res ) = @_; + log_if_fail "/aliases response for member", $res; + assert_json_nonempty_list( $res->{aliases} ); + + do_request_json_for( + $third_user, + method => "GET", + uri => "/r0/rooms/$room_id/aliases", + ); + })->main::expect_http_403; + }; From 10fa04f9124344df5c3b704ea778eb63870e82fb Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:31:08 +0000 Subject: [PATCH 07/42] Move /rooms/:room_id/aliases onto an unstable prefix (#810) --- tests/10apidoc/32room-alias.pl | 4 ++-- tests/30rooms/05aliases.pl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/10apidoc/32room-alias.pl b/tests/10apidoc/32room-alias.pl index 9ffe20146..0f95466a9 100644 --- a/tests/10apidoc/32room-alias.pl +++ b/tests/10apidoc/32room-alias.pl @@ -63,7 +63,7 @@ do_request_json_for( $user, method => "GET", - uri => "/r0/rooms/$room_id/aliases", + uri => "/unstable/org.matrix.msc2432/rooms/$room_id/aliases", ); })->then( sub { my ( $res ) = @_; @@ -84,7 +84,7 @@ do_request_json_for( $user, method => "GET", - uri => "/r0/rooms/$room_id/aliases", + uri => "/unstable/org.matrix.msc2432/rooms/$room_id/aliases", ); })->then( sub { my ( $res ) = @_; diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index 705e995a3..f9e4c2188 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -352,7 +352,7 @@ sub _test_can_create_and_delete_alias { do_request_json_for( $other_user, method => "GET", - uri => "/r0/rooms/$room_id/aliases", + uri => "/unstable/org.matrix.msc2432/rooms/$room_id/aliases", ); })->then( sub { my ( $res ) = @_; @@ -362,7 +362,7 @@ sub _test_can_create_and_delete_alias { do_request_json_for( $third_user, method => "GET", - uri => "/r0/rooms/$room_id/aliases", + uri => "/unstable/org.matrix.msc2432/rooms/$room_id/aliases", ); })->main::expect_http_403; }; From cd7b73b108efc5bc75f8f70364425ebeb9ba3a62 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 19 Feb 2020 07:39:49 -0500 Subject: [PATCH 08/42] Port changes from 30rooms/70publicroomslist.pl to 50federation/40publicroomlist.pl to fix flaky test. --- tests/50federation/40publicroomlist.pl | 137 +++++++++++++------------ 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/tests/50federation/40publicroomlist.pl b/tests/50federation/40publicroomlist.pl index a44f27cc4..3eb3de4ff 100644 --- a/tests/50federation/40publicroomlist.pl +++ b/tests/50federation/40publicroomlist.pl @@ -29,74 +29,85 @@ visibility => "public", room_alias_name => $alias_local, %$room, - ) + )->on_done( sub { + my ( $room_id ) = @_; + log_if_fail "Created room $room_id with alias $alias_local"; + }); } keys %rooms ) ->then( sub { - $client->do_request_json( - method => "GET", - hostname => $server_name, - uri => "/v1/publicRooms", - ) - })->then( sub { - my ( $body ) = @_; - - log_if_fail "publicRooms", $body; - - assert_json_keys( $body, qw( chunk )); - assert_json_list( $body->{chunk} ); - - my %seen = map { - $_ => 0, - } keys ( %rooms ); - - foreach my $room ( @{ $body->{chunk} } ) { - assert_json_keys( $room, - qw( world_readable guest_can_join num_joined_members ) - ); - - my $name = $room->{name}; - my $topic = $room->{topic}; - my $canonical_alias = $room->{canonical_alias}; - - my $aliases = $room->{aliases}; - defined $aliases or next; - - foreach my $alias ( @{$aliases} ) { - foreach my $alias_local ( keys %rooms ) { - $alias =~ m/^\Q#$alias_local:\E/ or next; - - my $room_config = $rooms{$alias_local}; - - log_if_fail "Alias", $alias_local; - log_if_fail "Room", $room; - - assert_eq( $canonical_alias, $alias, "canonical alias" ); - assert_eq( $room->{num_joined_members}, 1, "num_joined_members" ); - - if( defined $name ) { - assert_eq( $room_config->{name}, $name, 'room name' ); - } - else { - defined $room_config->{name} and die "Expected not to find a name"; - } - - if( defined $topic ) { - assert_eq( $room_config->{topic}, $topic, 'room topic' ); - } - else { - defined $room_config->{topic} and die "Expected not to find a topic"; + my $iter = 0; + retry_until_success { + $client->do_request_json( + method => "GET", + hostname => $server_name, + uri => "/v1/publicRooms", + )->then( sub { + my ($body) = @_; + + $iter++; + log_if_fail "Iteration $iter: publicRooms result", $body; + + assert_json_keys($body, qw(chunk)); + assert_json_list($body->{chunk}); + + my %seen = map { + $_ => 0, + } keys(%rooms); + + foreach my $room (@{$body->{chunk}}) { + assert_json_keys($room, + qw(world_readable guest_can_join num_joined_members) + ); + + my $name = $room->{name}; + my $topic = $room->{topic}; + my $canonical_alias = $room->{canonical_alias}; + + my $aliases = $room->{aliases}; + defined $aliases or next; + + foreach my $alias (@{$aliases}) { + foreach my $alias_local (keys %rooms) { + $alias =~ m/^\Q#$alias_local:\E/ or next; + + my $room_config = $rooms{$alias_local}; + + log_if_fail "Alias", $alias_local; + log_if_fail "Room", $room; + + assert_eq($canonical_alias, $alias, "canonical alias"); + assert_eq($room->{num_joined_members}, 1, "num_joined_members"); + + if (defined $name) { + assert_eq($room_config->{name}, $name, 'room name'); + } + else { + defined $room_config->{name} and die "Expected not to find a name"; + } + + if (defined $topic) { + assert_eq($room_config->{topic}, $topic, 'room topic'); + } + else { + defined $room_config->{topic} and die "Expected not to find a topic"; + } + + $seen{$alias_local} = 1; + last; + } } - - $seen{$alias_local} = 1; - last; } - } - } - foreach my $key ( keys %seen ) { - $seen{$key} or die "Did not find a /publicRooms result for $key"; - } + foreach my $key (keys %seen) { + $seen{$key} or die "Did not find a /publicRooms result for $key"; + } - Future->done(1); + Future->done(1); + })->on_fail(sub { + my ($exc) = @_; + chomp $exc; + log_if_fail "Iteration $iter: not ready yet: $exc"; + }); + }; }) } From 52b419cc1f3aed7e11b9e3fffbb3fce5835c35b9 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 19 Feb 2020 12:51:55 -0500 Subject: [PATCH 09/42] Add tests for moving alt_aliases to an upgraded room. --- tests/30rooms/60version_upgrade.pl | 33 ++++++------------------------ 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/tests/30rooms/60version_upgrade.pl b/tests/30rooms/60version_upgrade.pl index 4e847e5c2..d2f65c649 100644 --- a/tests/30rooms/60version_upgrade.pl +++ b/tests/30rooms/60version_upgrade.pl @@ -679,7 +679,8 @@ sub upgrade_room_synced { matrix_put_room_state( $creator, $room_id, type => "m.room.canonical_alias", content => { - alias => $room_alias_1, + alias => $room_alias_1, + alt_aliases => [$room_alias_2], }, ); })->then( sub { @@ -692,17 +693,6 @@ sub upgrade_room_synced { ); })->then( sub { ( $new_room_id ) = @_; - - # m.room.aliases are filtered out until a better solution to mitigating abuse is is specced. - # - # matrix_get_room_state( - # $creator, $room_id, - # type=>'m.room.aliases', state_key=>$server_name, - # ); - # })->then( sub { - # my ( $old_aliases ) = @_; - # assert_deeply_eq( $old_aliases, {aliases => []}, "aliases on old room" ); - matrix_get_room_state( $creator, $room_id, type=>'m.room.canonical_alias' ); })->then( sub { my ( $old_canonical_alias ) = @_; @@ -710,20 +700,6 @@ sub upgrade_room_synced { $old_canonical_alias, {}, "canonical_alias on old room", ); - # m.room.aliases are filtered out until a better solution to mitigating abuse is is specced. - # - # matrix_get_room_state( - # $creator, $new_room_id, - # type=>'m.room.aliases', state_key=>$server_name, - # ); - # })->then( sub { - # my ( $new_aliases ) = @_; - # assert_deeply_eq( - # [ sort( @{ $new_aliases->{aliases} } ) ], - # [ sort( $room_alias_1, $room_alias_2 ) ], - # "aliases on new room", - # ); - matrix_get_room_state( $creator, $new_room_id, type=>'m.room.canonical_alias', ); @@ -731,7 +707,10 @@ sub upgrade_room_synced { my ( $new_canonical_alias ) = @_; assert_deeply_eq( $new_canonical_alias, - { alias => $room_alias_1 }, + { + alias => $room_alias_1, + alt_aliases => [$room_alias_2], + }, "canonical_alias on new room", ); From 66aefb701822c33c3f4d71da26b35ca1fed7195a Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 19 Feb 2020 18:06:02 +0000 Subject: [PATCH 10/42] Support running Dendrite in more than 1 sqlite db file Rather than use a single .db file and share it among all microservices, use a separate .db file for each microservice. Also, make sure to include the `hs_dir` in the file path else dendrite servers will share the same DB causing much confusion and woe (notably naffka partition offsets get messed up). --- lib/SyTest/Homeserver/Dendrite.pm | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/SyTest/Homeserver/Dendrite.pm b/lib/SyTest/Homeserver/Dendrite.pm index dc18f1a63..37cd57622 100644 --- a/lib/SyTest/Homeserver/Dendrite.pm +++ b/lib/SyTest/Homeserver/Dendrite.pm @@ -102,12 +102,6 @@ sub _get_config $db_uri .= sprintf( " sslmode=%s", $db_config{args}->{sslmode} ); } - # POSTGRES not set or is 0, use sqlite - if( ! defined $ENV{'POSTGRES'} || $ENV{'POSTGRES'} == '0') { - print STDERR "\nUsing sqlite database\n"; - $db_uri = "file:dendrite.db"; - } - return ( version => 0, matrix => { @@ -142,7 +136,10 @@ sub _get_config }, database => { - map { $_ => $db_uri } qw( + # POSTGRES not set or is 0, use sqlite, which has separate .db files for each server + map { ( ! defined $ENV{'POSTGRES'} || $ENV{'POSTGRES'} == '0') ? + ($_ => "file:$self->{hs_dir}/" . $_ . ".db") : + ($_ => $db_uri) } qw( account device media_api sync_api room_server server_key federation_sender public_rooms_api naffka appservice ), From a55b987dc02cafc15f3a95cb216732e0fe3217fc Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Thu, 20 Feb 2020 11:03:00 -0500 Subject: [PATCH 11/42] Fix formatting from review. --- tests/30rooms/60version_upgrade.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/30rooms/60version_upgrade.pl b/tests/30rooms/60version_upgrade.pl index d2f65c649..f0fafd06d 100644 --- a/tests/30rooms/60version_upgrade.pl +++ b/tests/30rooms/60version_upgrade.pl @@ -679,8 +679,8 @@ sub upgrade_room_synced { matrix_put_room_state( $creator, $room_id, type => "m.room.canonical_alias", content => { - alias => $room_alias_1, - alt_aliases => [$room_alias_2], + alias => $room_alias_1, + alt_aliases => [ $room_alias_2 ], }, ); })->then( sub { @@ -709,7 +709,7 @@ sub upgrade_room_synced { $new_canonical_alias, { alias => $room_alias_1, - alt_aliases => [$room_alias_2], + alt_aliases => [ $room_alias_2 ], }, "canonical_alias on new room", ); From feef3e1c6981850558473e4d722325fd69c6f10e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 21 Feb 2020 13:52:39 +0000 Subject: [PATCH 12/42] Attempt to deflake a sytest (#816) This test was a bit flaky. The trouble was that there were three things that could triger a deice update notification: * Joining the room * Updating the device keys * Changing display name ... but we only checked for two update notifications, and didn't sanity-check that they were matching up. By adding another poll for update notifications, we can avoid getting out of sync. I also don't think we need the display_name update here. We can also tighten up the final check by making sure that the departed user doesn't appear in *any* syncs between the departure and the undeparted user's update arriving. --- tests/41end-to-end-keys/06-device-lists.pl | 72 +++++++++++++++++----- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/tests/41end-to-end-keys/06-device-lists.pl b/tests/41end-to-end-keys/06-device-lists.pl index f2da9fb90..4ed3b77e0 100644 --- a/tests/41end-to-end-keys/06-device-lists.pl +++ b/tests/41end-to-end-keys/06-device-lists.pl @@ -347,6 +347,8 @@ sub sync_until_user_in_device_list matrix_create_room( $creator )->then( sub { ( $room_id ) = @_; + matrix_sync( $creator ); + })->then( sub { matrix_invite_user_to_room( $creator, $remote_leaver, $room_id ) })->then( sub { matrix_join_room( $remote_leaver, $room_id ); @@ -355,38 +357,78 @@ sub sync_until_user_in_device_list })->then( sub { matrix_join_room( $remote2, $room_id ); })->then( sub { - matrix_sync( $creator ); + log_if_fail "Created and joined room"; + + # make sure we've received the device list update for remote_leaver's + # join to the room, otherwise we could get out of sync. + sync_until_user_in_device_list( $creator, $remote_leaver ); })->then( sub { - matrix_put_e2e_keys( $remote_leaver ) + + # there must be e2e keys for the devices, otherwise they don't appear in /query. + matrix_put_e2e_keys( $remote2, device_keys => { x => "x" } ); })->then( sub { - matrix_put_e2e_keys( $remote2 ) + matrix_put_e2e_keys( $remote_leaver, device_keys => { x => "y" } ); })->then( sub { sync_until_user_in_device_list( $creator, $remote_leaver ); + })->then( sub { - matrix_set_device_display_name( $remote_leaver, $remote_leaver->device_id, "test display name" ), - })->then( sub { - log_if_fail "Remote_leaver " . $remote_leaver->user_id . " set display name"; - sync_until_user_in_device_list( $creator, $remote_leaver ); + # sanity check: make sure that we've got the right update + do_request_json_for( $creator, + method => "POST", + uri => "/r0/keys/query", + + content => { + device_keys => { $remote_leaver->user_id => [ $remote_leaver->device_id ] }, + }, + )->then( sub { + my ( $body ) = @_; + + log_if_fail "keys after remote_leaver uploaded keys", $body; + assert_json_keys( $body, qw( device_keys )); + my $update = $body->{device_keys}->{ $remote_leaver->user_id }->{ $remote_leaver->device_id }; + assert_eq( $update->{x}, "y" ); + Future->done; + }); })->then( sub { - matrix_leave_room_synced( $remote_leaver, $room_id ) + + # now one of the remote users leaves the room... + matrix_leave_room_synced( $remote_leaver, $room_id ); })->then( sub { log_if_fail "Remote_leaver " . $remote_leaver->user_id . " left room"; + + # now /finally/ we can test what we came here for. Both remote users update their + # device keys, and we check that we only get an update for one of them. matrix_put_e2e_keys( $remote_leaver, device_keys => { updated => "keys" } ) })->then( sub { log_if_fail "Remote_leaver " . $remote_leaver->user_id . " updated keys"; matrix_put_e2e_keys( $remote2, device_keys => { updated => "keys" } ) })->then( sub { log_if_fail "Remote user 2 " . $remote2->user_id . " updated keys"; - sync_until_user_in_device_list( $creator, $remote2 ); - })->then( sub { - my ( $body ) = @_; - log_if_fail "Final body", $body; + # we wait for a sync in which remote2 appears in the changed list, and make + # sure that remote_leaver *doesn't* appear in the meantime. - any { $_ eq $remote_leaver->user_id } @{ $body->{device_lists}{changed} } - and die "user2 in changed list after leaving"; + my $wait_for_id = $remote2->user_id; + repeat_until_true { + matrix_sync_again( $creator, timeout => 1000 ) + ->then( sub { + my ( $body ) = @_; - Future->done(1); + log_if_fail "waiting for $wait_for_id in 'changed'", $body; + + return Future->done(0) unless + $body->{device_lists} && + $body->{device_lists}{changed}; + + my @changed_list = @{ $body->{device_lists}{changed} }; + any { $_ eq $remote_leaver->user_id } @changed_list + and die "remote_leaver " . $remote_leaver->user_id . " in changed list after leaving"; + + return Future->done( + any { $_ eq $wait_for_id } @changed_list + ); + }); + }; }); }; From 5835a10a6f5b852093b46d0b339ed88fae359deb Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 21 Feb 2020 09:22:11 -0500 Subject: [PATCH 13/42] Stop checking for aliases in the public room list. --- tests/30rooms/13guestaccess.pl | 52 ++++++++++++-------------- tests/30rooms/70publicroomslist.pl | 48 ++++++++++-------------- tests/50federation/40publicroomlist.pl | 46 ++++++++++------------- 3 files changed, 64 insertions(+), 82 deletions(-) diff --git a/tests/30rooms/13guestaccess.pl b/tests/30rooms/13guestaccess.pl index 7f310b0c8..20d2ada0d 100644 --- a/tests/30rooms/13guestaccess.pl +++ b/tests/30rooms/13guestaccess.pl @@ -365,29 +365,27 @@ my %isOK = map { $_ => 0 } keys %rooms; foreach my $room ( @{ $body->{chunk} } ) { - my $aliases = $room->{aliases}; + my $canonical_alias = $room->{canonical_alias}; assert_json_boolean( my $world_readable = $room->{world_readable} ); assert_json_boolean( my $guest_can_join = $room->{guest_can_join} ); - foreach my $alias ( @{$aliases} ) { - my $alias_local = first { $alias =~ m/^#$_:/ } keys %rooms; - next unless $alias_local; - my $settings = $rooms{$alias_local}; + my $alias_local = first { $canonical_alias =~ m/^#$_:/ } keys %rooms; + next unless $alias_local; + my $settings = $rooms{$alias_local}; - if(( $settings->{history_visibility} // "" ) eq "world_readable" ) { - $world_readable or die "Expected $alias_local to be world_readable"; - } else { - $world_readable and die "Expected $alias_local not to be world_readable"; - } - - if(( $settings->{guest_access} // "" ) eq "can_join" ) { - $guest_can_join or die "Expected $alias_local to be guest-joinable"; - } else { - $guest_can_join and die "Expected $alias_local not to be guest-joinable"; - } + if(( $settings->{history_visibility} // "" ) eq "world_readable" ) { + $world_readable or die "Expected $alias_local to be world_readable"; + } else { + $world_readable and die "Expected $alias_local not to be world_readable"; + } - $isOK{$alias_local} = 1; + if(( $settings->{guest_access} // "" ) eq "can_join" ) { + $guest_can_join or die "Expected $alias_local to be guest-joinable"; + } else { + $guest_can_join and die "Expected $alias_local not to be guest-joinable"; } + + $isOK{$alias_local} = 1; } foreach my $alias ( keys %rooms ) { @@ -462,17 +460,15 @@ ); foreach my $room ( @{ $body->{chunk} } ) { - my $aliases = $room->{aliases}; - - foreach my $alias ( @{$aliases} ) { - if( $alias =~ m/^\Q#worldreadable:/ ) { - $isOK{worldreadable} = - ( $room->{avatar_url} eq "https://example.com/ringtails.jpg" ); - } - elsif( $alias =~ m/^\Q#nonworldreadable:/ ) { - $isOK{nonworldreadable} = - ( $room->{avatar_url} eq "https://example.com/ruffed.jpg" ); - } + my $canonical_alias = $room->{canonical_alias}; + + if( $canonical_alias =~ m/^\Q#worldreadable:/ ) { + $isOK{worldreadable} = + ( $room->{avatar_url} eq "https://example.com/ringtails.jpg" ); + } + elsif( $canonical_alias =~ m/^\Q#nonworldreadable:/ ) { + $isOK{nonworldreadable} = + ( $room->{avatar_url} eq "https://example.com/ruffed.jpg" ); } } diff --git a/tests/30rooms/70publicroomslist.pl b/tests/30rooms/70publicroomslist.pl index 18d1a43ef..165d47a83 100644 --- a/tests/30rooms/70publicroomslist.pl +++ b/tests/30rooms/70publicroomslist.pl @@ -59,40 +59,32 @@ my $topic = $room->{topic}; my $canonical_alias = $room->{canonical_alias}; - my $aliases = $room->{aliases}; - if( not defined $aliases ) { - next; - } - - foreach my $alias ( @{$aliases} ) { - foreach my $alias_local ( keys %rooms ) { - $alias =~ m/^\Q#$alias_local:\E/ or next; + foreach my $alias_local ( keys %rooms ) { + $canonical_alias =~ m/^\Q#$alias_local:\E/ or next; - my $room_config = $rooms{$alias_local}; + my $room_config = $rooms{$alias_local}; - assert_eq( $canonical_alias, $alias, "canonical_alias" ); - assert_eq( $room->{num_joined_members}, 1, "member count for '$alias_local'" ); + assert_eq( $room->{num_joined_members}, 1, "member count for '$alias_local'" ); - # The rooms should get created "atomically", so we should never - # see any out of the public rooms list in the wrong state. If - # we see a room we expect it to already be in the right state. + # The rooms should get created "atomically", so we should never + # see any out of the public rooms list in the wrong state. If + # we see a room we expect it to already be in the right state. - if( defined $name ) { - assert_eq( $room_config->{name}, $name, "room name for '$alias_local'" ); - } - else { - defined $room_config->{name} and die "Expected not to find a name for '$alias_local'"; - } - - if( defined $topic ) { - assert_eq( $room_config->{topic}, $topic, "room topic for '$alias_local'" ); - } - else { - defined $room_config->{topic} and die "Expected not to find a topic for '$alias_local'"; - } + if( defined $name ) { + assert_eq( $room_config->{name}, $name, "room name for '$alias_local'" ); + } + else { + defined $room_config->{name} and die "Expected not to find a name for '$alias_local'"; + } - $isOK{$alias_local} = 1; + if( defined $topic ) { + assert_eq( $room_config->{topic}, $topic, "room topic for '$alias_local'" ); + } + else { + defined $room_config->{topic} and die "Expected not to find a topic for '$alias_local'"; } + + $isOK{$alias_local} = 1; } } diff --git a/tests/50federation/40publicroomlist.pl b/tests/50federation/40publicroomlist.pl index 3eb3de4ff..45989cad0 100644 --- a/tests/50federation/40publicroomlist.pl +++ b/tests/50federation/40publicroomlist.pl @@ -63,38 +63,32 @@ my $topic = $room->{topic}; my $canonical_alias = $room->{canonical_alias}; - my $aliases = $room->{aliases}; - defined $aliases or next; + foreach my $alias_local (keys %rooms) { + $canonical_alias =~ m/^\Q#$alias_local:\E/ or next; - foreach my $alias (@{$aliases}) { - foreach my $alias_local (keys %rooms) { - $alias =~ m/^\Q#$alias_local:\E/ or next; + my $room_config = $rooms{$alias_local}; - my $room_config = $rooms{$alias_local}; + log_if_fail "Alias", $alias_local; + log_if_fail "Room", $room; - log_if_fail "Alias", $alias_local; - log_if_fail "Room", $room; + assert_eq($room->{num_joined_members}, 1, "num_joined_members"); - assert_eq($canonical_alias, $alias, "canonical alias"); - assert_eq($room->{num_joined_members}, 1, "num_joined_members"); - - if (defined $name) { - assert_eq($room_config->{name}, $name, 'room name'); - } - else { - defined $room_config->{name} and die "Expected not to find a name"; - } - - if (defined $topic) { - assert_eq($room_config->{topic}, $topic, 'room topic'); - } - else { - defined $room_config->{topic} and die "Expected not to find a topic"; - } + if (defined $name) { + assert_eq($room_config->{name}, $name, 'room name'); + } + else { + defined $room_config->{name} and die "Expected not to find a name"; + } - $seen{$alias_local} = 1; - last; + if (defined $topic) { + assert_eq($room_config->{topic}, $topic, 'room topic'); + } + else { + defined $room_config->{topic} and die "Expected not to find a topic"; } + + $seen{$alias_local} = 1; + last; } } From f6db39c66c1d2b3fdf3b25ecac6873c0fb564424 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 3 Mar 2020 13:24:01 +0000 Subject: [PATCH 14/42] Fix frontend proxy worker binding to wrong port. (#823) Co-authored-by: Patrick Cloke --- docker/base.Dockerfile | 3 --- lib/SyTest/Homeserver/Synapse.pm | 8 +++++++- scripts/synapse_sytest.sh | 23 ++++++++++++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/docker/base.Dockerfile b/docker/base.Dockerfile index b06b63535..91ac6f64c 100644 --- a/docker/base.Dockerfile +++ b/docker/base.Dockerfile @@ -60,6 +60,3 @@ ENV PGHOST=/var/run/postgresql ENV PGDATA=$PGHOST/data ENV PGUSER=postgres RUN for ver in `ls /usr/lib/postgresql | head -n 1`; do su -c '/usr/lib/postgresql/'$ver'/bin/initdb -E "UTF-8" --lc-collate="C" --lc-ctype="C" --username=postgres' postgres; done - -# Turn off all the fsync stuff for postgres -RUN for ver in /etc/postgresql/*/main; do mkdir -p $ver/conf.d/; echo -e "fsync=off\nfull_page_writes=off" >> $ver/conf.d/fsync.conf; done diff --git a/lib/SyTest/Homeserver/Synapse.pm b/lib/SyTest/Homeserver/Synapse.pm index 015731bd3..bef808621 100644 --- a/lib/SyTest/Homeserver/Synapse.pm +++ b/lib/SyTest/Homeserver/Synapse.pm @@ -703,6 +703,7 @@ sub wrap_synapse_command "worker_log_config" => $self->configure_logger("pusher"), "worker_replication_host" => "$bind_host", "worker_replication_port" => $self->{ports}{synapse_replication_tcp}, + "worker_replication_http_port" => $self->{ports}{synapse_unsecure}, "worker_listeners" => [ { type => "http", @@ -728,6 +729,7 @@ sub wrap_synapse_command "worker_log_config" => $self->configure_logger("appservice"), "worker_replication_host" => "$bind_host", "worker_replication_port" => $self->{ports}{synapse_replication_tcp}, + "worker_replication_http_port" => $self->{ports}{synapse_unsecure}, "worker_listeners" => [ { type => "manhole", @@ -753,6 +755,7 @@ sub wrap_synapse_command "worker_log_config" => $self->configure_logger("federation_sender"), "worker_replication_host" => "$bind_host", "worker_replication_port" => $self->{ports}{synapse_replication_tcp}, + "worker_replication_http_port" => $self->{ports}{synapse_unsecure}, "worker_listeners" => [ { type => "manhole", @@ -778,6 +781,7 @@ sub wrap_synapse_command "worker_log_config" => $self->configure_logger("synchrotron"), "worker_replication_host" => "$bind_host", "worker_replication_port" => $self->{ports}{synapse_replication_tcp}, + "worker_replication_http_port" => $self->{ports}{synapse_unsecure}, "worker_listeners" => [ { type => "http", @@ -845,6 +849,7 @@ sub wrap_synapse_command "worker_log_config" => $self->configure_logger("media_repository"), "worker_replication_host" => "$bind_host", "worker_replication_port" => $self->{ports}{synapse_replication_tcp}, + "worker_replication_http_port" => $self->{ports}{synapse_unsecure}, "worker_listeners" => [ { type => "http", @@ -912,6 +917,7 @@ sub wrap_synapse_command "worker_log_config" => $self->configure_logger("user_dir"), "worker_replication_host" => "$bind_host", "worker_replication_port" => $self->{ports}{synapse_replication_tcp}, + "worker_replication_http_port" => $self->{ports}{synapse_unsecure}, "worker_listeners" => [ { type => "http", @@ -990,7 +996,7 @@ sub wrap_synapse_command }, { type => "manhole", - port => $self->{ports}{frontend_proxy}, + port => $self->{ports}{frontend_proxy_manhole}, bind_address => $bind_host, }, { diff --git a/scripts/synapse_sytest.sh b/scripts/synapse_sytest.sh index e94ca365d..d13c8b2d1 100755 --- a/scripts/synapse_sytest.sh +++ b/scripts/synapse_sytest.sh @@ -16,15 +16,26 @@ cd "$(dirname $0)/.." mkdir /work # PostgreSQL setup -if [ -n "$MULTI_POSTGRES" ]; then - # In this mode we want to run synapse against multiple split out databases. - +if [ -n "$MULTI_POSTGRES" ] || [ -n "$POSTGRES" ]; then # We increase the max connections as we have more databases. - echo -e "max_connections=1000" >> /var/run/postgresql/data/postgresql.conf + sed -i -r "s/^max_connections.*$/max_connections = 500/" /var/run/postgresql/data/postgresql.conf + + echo -e "fsync = off" >> /var/run/postgresql/data/postgresql.conf + echo -e "full_page_writes = off" >> /var/run/postgresql/data/postgresql.conf # Start the database su -c 'eatmydata /usr/lib/postgresql/*/bin/pg_ctl -w -D $PGDATA start' postgres + su -c psql postgres <<< "show config_file" + su -c psql postgres <<< "show max_connections" + su -c psql postgres <<< "show full_page_writes" + su -c psql postgres <<< "show fsync" +fi + +# Now create the databases +if [ -n "$MULTI_POSTGRES" ]; then + # In this mode we want to run synapse against multiple split out databases. + # Make the test databases for the two Synapse servers that will be spun up su -c psql postgres < Date: Fri, 28 Feb 2020 12:30:50 -0500 Subject: [PATCH 15/42] Attempt to deflake a test. --- tests/30rooms/13guestaccess.pl | 42 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/tests/30rooms/13guestaccess.pl b/tests/30rooms/13guestaccess.pl index 20d2ada0d..583c2e3ee 100644 --- a/tests/30rooms/13guestaccess.pl +++ b/tests/30rooms/13guestaccess.pl @@ -172,26 +172,28 @@ displayname => "creeper", }, )})->then( sub { - Future->needs_all( - do_request_json_for( $guest_user, - method => "GET", - uri => $displayname_uri, - )->then( sub { - my ( $body ) = @_; - assert_eq( $body->{displayname}, "creeper", "Profile displayname" ); - - Future->done(1); - }), - do_request_json_for( $guest_user, - method => "GET", - uri => "/r0/rooms/$room_id/state/m.room.member/:user_id", - )->then( sub { - my ( $body ) = @_; - assert_eq( $body->{displayname}, "creeper", "Room displayname" ); - - Future->done(1); - }), - ); + repeat_until_true { + Future->needs_all( + do_request_json_for( $guest_user, + method => "GET", + uri => $displayname_uri, + )->then( sub { + my ( $body ) = @_; + assert_eq( $body->{displayname}, "creeper", "Profile displayname" ); + + Future->done(1); + }), + do_request_json_for( $guest_user, + method => "GET", + uri => "/r0/rooms/$room_id/state/m.room.member/:user_id", + )->then( sub { + my ( $body ) = @_; + assert_eq( $body->{displayname}, "creeper", "Room displayname" ); + + Future->done(1); + }), + ); + } }); }; From da4231b0d139711e3054bb3755c7d9b3e5a1a77f Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 3 Mar 2020 09:31:48 -0500 Subject: [PATCH 16/42] Use retry_until_success instead of repeat_until_true. --- tests/30rooms/13guestaccess.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/30rooms/13guestaccess.pl b/tests/30rooms/13guestaccess.pl index 583c2e3ee..89a03e4a6 100644 --- a/tests/30rooms/13guestaccess.pl +++ b/tests/30rooms/13guestaccess.pl @@ -172,7 +172,7 @@ displayname => "creeper", }, )})->then( sub { - repeat_until_true { + retry_until_success { Future->needs_all( do_request_json_for( $guest_user, method => "GET", From ee33ef362b0fdf6c8a21c4d6b666c37506ad76c8 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 3 Mar 2020 15:38:21 +0000 Subject: [PATCH 17/42] Fix race in self signing key tests. (#822) --- tests/41end-to-end-keys/08-cross-signing.pl | 47 +++++++++++---------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/tests/41end-to-end-keys/08-cross-signing.pl b/tests/41end-to-end-keys/08-cross-signing.pl index 9fd255e9b..ce39b5eb1 100644 --- a/tests/41end-to-end-keys/08-cross-signing.pl +++ b/tests/41end-to-end-keys/08-cross-signing.pl @@ -555,28 +555,31 @@ })->then( sub { sync_until_user_in_device_list( $user1, $user2 ); })->then( sub { - matrix_get_e2e_keys( $user1, $user2_id ); - })->then( sub { - my ( $content ) = @_; - - log_if_fail "key query content", $content; - - assert_json_keys( $content, "master_keys" ); - assert_json_keys( $content->{master_keys}, $user2_id ); - assert_deeply_eq( $content->{master_keys}->{$user2_id}, { - "user_id" => $user2_id, - "usage" => ["master"], - "keys" => { - "ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk" - => "nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk", - }, - }, - ); - assert_json_keys( $content, "self_signing_keys" ); - assert_json_keys( $content->{self_signing_keys}, $user2_id ); - assert_deeply_eq( $content->{self_signing_keys}->{$user2_id}, $self_signing_key); - - Future->done(1); + retry_until_success { + matrix_get_e2e_keys( $user1, $user2_id ) + ->then( sub { + my ( $content ) = @_; + + log_if_fail "key query content", $content; + + assert_json_keys( $content, "master_keys" ); + assert_json_keys( $content->{master_keys}, $user2_id ); + assert_deeply_eq( $content->{master_keys}->{$user2_id}, { + "user_id" => $user2_id, + "usage" => ["master"], + "keys" => { + "ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk" + => "nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk", + }, + }, + ); + assert_json_keys( $content, "self_signing_keys" ); + assert_json_keys( $content->{self_signing_keys}, $user2_id ); + assert_deeply_eq( $content->{self_signing_keys}->{$user2_id}, $self_signing_key); + + Future->done(1); + }) + } }); }; From bee7c3267310548b985fc788bb9ebefc7d8694d7 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Wed, 4 Mar 2020 15:37:13 +0000 Subject: [PATCH 18/42] Fix the CAS login test (#826) --- tests/12login/02cas.pl | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tests/12login/02cas.pl b/tests/12login/02cas.pl index 854b4956a..824f0286c 100644 --- a/tests/12login/02cas.pl +++ b/tests/12login/02cas.pl @@ -161,7 +161,7 @@ sub wait_for_cas_request method => "GET", full_uri => $login_uri, max_redirects => 0, # don't follow the redirect - )->followed_by( \&main::expect_http_302 ), + ), ); })->then( sub { my ( $cas_validate_request, $ticket_response ) = @_; @@ -175,19 +175,12 @@ sub wait_for_cas_request $HS_URI, "Service supplied to /cas/proxyValidate" ); - my $redirect = $ticket_response->header( "Location" ); - log_if_fail( "Redirect from /login/cas/ticket", $redirect); - assert_ok( $redirect =~ m#^https://client\?#, - "Location returned by /login/cas/ticket did not match" ); - - # the original query param should have been preserved - my $redirect_uri = URI->new($redirect); - assert_eq( $redirect_uri->query_param( "p" ) // undef, - "http://server", - "Query param on redirect from /login/cas/ticket" ); + assert_ok( $ticket_response =~ "loginToken=([^\"&]+)", + "Login token provided in the /ticket response" ); + my $login_token = $1; - # a 'loginToken' should be added. - my $login_token = $redirect_uri->query_param( "loginToken" ); + log_if_fail( "Ticket response:", $ticket_response ); + log_if_fail( "Login token:", $login_token ); # step 7: the client uses the loginToken via the /login API. $http->do_request_json( From 7c8890f67247dcddeffba3430ce97ebdcdff254c Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 4 Mar 2020 11:25:27 -0500 Subject: [PATCH 19/42] Add a test for an event with an invalid signature (#821) --- tests/50federation/30room-join.pl | 107 +++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/tests/50federation/30room-join.pl b/tests/50federation/30room-join.pl index 169e2be87..a6dab2d28 100644 --- a/tests/50federation/30room-join.pl +++ b/tests/50federation/30room-join.pl @@ -870,7 +870,7 @@ sub assert_is_valid_pdu { # XXX currently synapse fails with a 500 here. I'm not really convinced that's # a thing we want to enforce, but we don't really have a specced way to say - # "a remote server did something wierd". + # "a remote server did something weird". Future->done(1); }), ) @@ -953,7 +953,110 @@ sub assert_is_valid_pdu { # XXX currently synapse fails with a 500 here. I'm not really convinced that's # a thing we want to enforce, but we don't really have a specced way to say - # "a remote server did something wierd". + # "a remote server did something weird". + Future->done(1); + }), + ) + }; + +test "Event with an invalid signature in the send_join response should not cause room join to fail", + requires => [ local_user_fixture(), $main::INBOUND_SERVER, + federation_user_id_fixture() ], + + do => sub { + my ( $user, $inbound_server, $creator_id ) = @_; + + my $local_server_name = $inbound_server->server_name; + my $datastore = $inbound_server->datastore; + + my $room_alias = "#50fed-room-alias-invalid-sig:$local_server_name"; + my $room = $datastore->create_room( + creator => $creator_id, + alias => $room_alias, + ); + + my $room_id = $room->room_id; + + my $event = $room->create_and_insert_event( + sender => "\@test:$local_server_name", + type => "test", + room_id => $room_id, + state_key => "", + content => { + body => "Test", + }, + ); + + # Modify the event (after the signature was generated) to invalidate the signature. + $event->{origin} = "other-server:12345"; + + my $await_request_send_join; + + $await_request_send_join = $inbound_server->await_request_v2_send_join( $room_id ); + + Future->needs_all( + $inbound_server->await_request_make_join( $room_id, $user->user_id )->then( sub { + my ( $req, $room_id, $user_id ) = @_; + + my $proto = $room->make_join_protoevent( + user_id => $user_id, + ); + + $proto->{origin} = $inbound_server->server_name; + $proto->{origin_server_ts} = $inbound_server->time_ms; + + $req->respond_json( { + event => $proto, + } ); + + Future->done; + }), + + $await_request_send_join->then( sub { + my ( $req, $room_id, $event_id ) = @_; + + $req->method eq "PUT" or + die "Expected send_join method to be PUT"; + + my $event = $req->body_from_json; + log_if_fail "send_join event", $event; + + my @auth_chain = $datastore->get_auth_chain_events( + map { $_->[0] } @{ $event->{auth_events} } + ); + + my $response = { + auth_chain => \@auth_chain, + state => [ $room->current_state_events ], + }; + + $req->respond_json($response); + + log_if_fail "send_join response", $response; + + Future->done; + }), + + do_request_json_for( $user, + method => "POST", + uri => "/r0/join/$room_alias", + + content => {}, + )->then( sub { + my ( $body ) = @_; + log_if_fail "Join response", $body; + + assert_json_keys( $body, qw( room_id )); + + $body->{room_id} eq $room_id or + die "Expected room_id to be $room_id"; + + matrix_get_my_member_event( $user, $room_id ) + })->then( sub { + my ( $event ) = @_; + + assert_json_keys( $event->{content}, qw( membership ) ); + Future->done(1); }), ) From 9113b5646096c1ad827b49fd742833b272baae8b Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 4 Mar 2020 11:30:56 -0500 Subject: [PATCH 20/42] Add tests for a user with sufficient power level removing an alias. (#818) --- tests/30rooms/05aliases.pl | 51 ++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index f9e4c2188..fe9da3f37 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -135,8 +135,6 @@ do => sub { my ( $creator, $other_user, $room_id, $alias ) = @_; - my $server_name = $other_user->http->server_name; - matrix_change_room_power_levels( $creator, $room_id, sub { $_[0]->{events}->{'m.room.aliases'} = 50; @@ -169,8 +167,6 @@ sub _test_can_create_and_delete_alias { my ( $room_id, $user, $alias ) = @_; - my $server_name = $user->http->server_name; - do_request_json_for( $user, method => "PUT", uri => "/r0/directory/room/$alias", @@ -209,7 +205,6 @@ sub _test_can_create_and_delete_alias { do => sub { my ( $user, $room_id, $other_user, $room_alias ) = @_; - my $server_name = $user->http->server_name; do_request_json_for( $user, method => "PUT", @@ -226,6 +221,50 @@ sub _test_can_create_and_delete_alias { }) }; +test "Users with sufficient power-level can delete other's aliases", + requires => [ $creator_fixture, local_user_fixture(), room_alias_fixture(), + qw( can_create_room_alias )], + + do => sub { + my ( $user, $other_user, $room_alias ) = @_; + my $room_id; + + matrix_create_and_join_room( + [ $user, $other_user ], + )->then( sub { + ( $room_id ) = @_; + + matrix_change_room_power_levels( + $user, $room_id, sub { + $_[0]->{users}->{$other_user->user_id} = 100; + }, + ) + })->then( sub { + do_request_json_for( $user, + method => "PUT", + uri => "/r0/directory/room/$room_alias", + + content => { room_id => $room_id }, + ) + })->then( sub { + do_request_json_for( $other_user, + method => "DELETE", + uri => "/r0/directory/room/$room_alias", + + content => {}, + ) + })->then( sub { + my ( $res ) = @_; + log_if_fail "Unable to delete alias", $res; + + do_request_json_for( + $user, + method => "GET", + uri => "/r0/directory/room/$room_alias", + ); + })->main::expect_http_404; + }; + test "Can delete canonical alias", requires => [ local_user_fixture( with_events => 0 ), room_alias_fixture(), qw( can_create_room_alias )], @@ -275,7 +314,6 @@ sub _test_can_create_and_delete_alias { do => sub { my ( $creator, $other_user, $room_alias ) = @_; - my $server_name = $creator->http->server_name; my $room_id; matrix_create_and_join_room( [ $creator, $other_user ] ) @@ -305,7 +343,6 @@ sub _test_can_create_and_delete_alias { do => sub { my ( $creator, $other_user, $room_alias ) = @_; - my $server_name = $creator->http->server_name; my $room_id; matrix_create_and_join_room( [ $creator, $other_user ] ) From 955648a44d9ba20650ff6b518249585ff28899a9 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 9 Mar 2020 07:18:54 -0400 Subject: [PATCH 21/42] Update the haproxy config to route fallback auth and register to the same worker. (#828) --- lib/SyTest/Homeserver/Synapse.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/SyTest/Homeserver/Synapse.pm b/lib/SyTest/Homeserver/Synapse.pm index bef808621..1d2d9d18d 100644 --- a/lib/SyTest/Homeserver/Synapse.pm +++ b/lib/SyTest/Homeserver/Synapse.pm @@ -1204,6 +1204,7 @@ sub generate_haproxy_map ^/_matrix/client/versions$ client_reader ^/_matrix/client/(api/v1|r0|unstable)/voip/turnServer$ client_reader ^/_matrix/client/(r0|unstable)/register$ client_reader +^/_matrix/client/(r0|unstable)/auth/.*/fallback/web$ client_reader ^/_matrix/client/(api/v1|r0|unstable)/rooms/.*/messages$ client_reader ^/_matrix/client/(api/v1|r0|unstable)/get_groups_publicised$ client_reader ^/_matrix/client/(api/v1|r0|unstable)/joined_groups$ client_reader From 7beff409a081ec088c2d935ff1748dadaa1fe3dd Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 16 Mar 2020 07:30:05 -0400 Subject: [PATCH 22/42] Add tests for validating alt_aliases of a canonical alias event. (#824) --- tests/30rooms/05aliases.pl | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index fe9da3f37..aacd69301 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -90,6 +90,7 @@ } )->SyTest::pass_on_done( "m.room.canonical_alias accepts present aliases" ); })->then( sub { + # Create an unknown, but valid alias name. my $bad_alias = $room_alias =~ s/^#/#NOT-/r; matrix_put_room_state( $user, $room_id, @@ -99,6 +100,84 @@ } )->main::expect_http_4xx ->SyTest::pass_on_done( "m.room.canonical_alias rejects missing aliases" ); + })->then( sub { + # Create an invalid alias name (starts with % instead of #). + my $bad_alias = $room_alias =~ s/^#/%/r; + + matrix_put_room_state( $user, $room_id, + type => "m.room.canonical_alias", + content => { + alias => $bad_alias, + } + )->main::expect_http_4xx + ->SyTest::pass_on_done( "m.room.canonical_alias rejects invalid aliases" ); + }); + }; + +multi_test "Canonical alias can include alt_aliases", + requires => [ local_user_fixture(), room_alias_name_fixture() ], + + do => sub { + my ( $user, $room_alias_name ) = @_; + + my ( $room_id, $room_alias ); + + matrix_create_room( $user, + room_alias_name => $room_alias_name, + )->then( sub { + ( $room_id, $room_alias ) = @_; + + matrix_put_room_state( $user, $room_id, + type => "m.room.canonical_alias", + content => { + alias => $room_alias, + alt_aliases => [ $room_alias ], + } + )->SyTest::pass_on_done( "m.room.canonical_alias accepts present aliases" ); + })->then( sub { + # Create an unknown, but valid alias name. + my $bad_alias = $room_alias =~ s/^#/#NOT-/r; + + matrix_put_room_state( $user, $room_id, + type => "m.room.canonical_alias", + content => { + alias => $room_alias, + alt_aliases => [ $bad_alias ], + } + )->main::expect_matrix_error( 404, "M_NOT_FOUND" ) + ->SyTest::pass_on_done( "m.room.canonical_alias rejects missing aliases" ); + })->then( sub { + # Create an invalid alias name (starts with % instead of #). + my $bad_alias = $room_alias =~ s/^#/%/r; + + matrix_put_room_state( $user, $room_id, + type => "m.room.canonical_alias", + content => { + alias => $room_alias, + alt_aliases => [ $bad_alias ], + } + )->main::expect_matrix_error( 400, "M_INVALID_PARAM" ) + ->SyTest::pass_on_done( "m.room.canonical_alias rejects invalid aliases" ); + })->then( sub { + # Create a second room with an alias on it. + my $other_alias_name = $room_alias_name . "2"; + + matrix_create_room( $user, + room_alias_name => $other_alias_name, + )->then( sub { + my ( $other_room_id, $other_room_alias ) = @_; + + # Attempt to set a canonical alias for the original room using an + # alias from the second room. + matrix_put_room_state( $user, $room_id, + type => "m.room.canonical_alias", + content => { + alias => $room_alias, + alt_aliases => [ $other_room_alias ], + } + )->main::expect_matrix_error( 400, "M_BAD_ALIAS" ) + ->SyTest::pass_on_done( "m.room.canonical_alias rejects alias pointing to different room" ); + }) }); }; From 51e6d2f2de746d49a3db770c2b261d0a51c7530e Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 17 Mar 2020 10:23:53 -0400 Subject: [PATCH 23/42] Remove tests that call query_auth endpoint. (#827) --- tests/50federation/42query-auth.pl | 42 -------------------- tests/50federation/50server-acl-endpoints.pl | 19 --------- 2 files changed, 61 deletions(-) delete mode 100644 tests/50federation/42query-auth.pl diff --git a/tests/50federation/42query-auth.pl b/tests/50federation/42query-auth.pl deleted file mode 100644 index 29a9e6147..000000000 --- a/tests/50federation/42query-auth.pl +++ /dev/null @@ -1,42 +0,0 @@ -use Future::Utils qw( repeat ); - -test "Querying auth checks the events requested belong to the room", - requires => [ $main::OUTBOUND_CLIENT, - local_user_and_room_fixtures(), - local_user_and_room_fixtures(), - federation_user_id_fixture() ], - do => sub { - my ( $outbound_client, $priv_creator, $priv_room_id, - $pub_creator, $pub_room_id, $fed_user_id ) = @_; - my $first_home_server = $pub_creator->server_name; - - my $local_server_name = $outbound_client->server_name; - - my $priv_join_event; - - # Join the public room, but don't touch the private one - $outbound_client->join_room( - server_name => $first_home_server, - room_id => $pub_room_id, - user_id => $fed_user_id, - )->then( sub { - # Send an event into the private room - matrix_send_room_text_message( $priv_creator, $priv_room_id, - body => "Hello world", - ) - })->then( sub { - my ( $priv_event_id ) = @_; - - # We specifically use the public room, but the private event ID - # That's the point of this test. - $outbound_client->do_request_json( - method => "POST", - hostname => $first_home_server, - uri => "/v1/query_auth/$pub_room_id/$priv_event_id", - - content => { - auth_chain => [], # This is part of the exploit - } - )->main::expect_m_not_found; - }); - }; diff --git a/tests/50federation/50server-acl-endpoints.pl b/tests/50federation/50server-acl-endpoints.pl index c8ef3eea6..400b2a72c 100644 --- a/tests/50federation/50server-acl-endpoints.pl +++ b/tests/50federation/50server-acl-endpoints.pl @@ -28,7 +28,6 @@ [ "get room state ids", *can_get_state_ids ], [ "backfill", *can_backfill ], [ "/event_auth", *can_event_auth ], - [ "query auth", *can_query_auth ], [ "get missing events", *can_get_missing_events ], ); @@ -240,24 +239,6 @@ sub can_event_auth { ); } -sub can_query_auth { - my ( %params ) = @_; - my $room = $params{room}; - my $room_id = $room->{room_id}; - my $event_id = $room->id_for_event($room->{prev_events}[-1]); - - maybe_expect_forbidden( - $params{outbound_client}->do_request_json( - method => "POST", - hostname => $params{dest_server}, - uri => "/v1/query_auth/$room_id/$event_id", - content => { - auth_chain => [], - }, - ), $params{expect_ban}, "/query_auth", - ); -} - sub can_get_missing_events { my ( %params ) = @_; my $room = $params{room}; From c0c8009b2a736694823a1a92dadccaa41f61e638 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 18 Mar 2020 07:50:21 -0400 Subject: [PATCH 24/42] Add test to optionally keep other sessions when modifying a user's password. (#832) --- tests/14account/01change-password.pl | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/14account/01change-password.pl b/tests/14account/01change-password.pl index 48dab76c5..7bfab0d8e 100644 --- a/tests/14account/01change-password.pl +++ b/tests/14account/01change-password.pl @@ -82,7 +82,7 @@ sub matrix_set_password })->then_done(1); }; -test "After changing password, a different session no longer works", +test "After changing password, a different session no longer works by default", requires => [ local_user_fixture( password => $password ) ], check => sub { @@ -107,6 +107,38 @@ sub matrix_set_password })->then_done(1); }; +test "After changing password, different sessions can optionally be kept", + requires => [ local_user_fixture( password => $password ) ], + + check => sub { + my ( $user ) = @_; + + my $other_login; + + matrix_login_again_with_user( $user )->then( sub { + ( $other_login ) = @_; + # ensure other login works to start with + matrix_sync( $other_login ); + })->then( sub { + do_request_json_for( $user, + method => "POST", + uri => "/r0/account/password", + content => { + auth => { + type => "m.login.password", + user => $user->user_id, + password => $password, + }, + new_password => "my new password", + logout_devices => JSON::false, + }, + ); + })->then( sub { + # The access token should still be valid. + matrix_sync( $other_login ); + })->then_done(1); + }; + test "Pushers created with a different access token are deleted on password change", requires => [ local_user_fixture( password => $password ) ], From bd6eb85fa741cc5f28968ca897bec22792482551 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 18 Mar 2020 16:02:09 +0000 Subject: [PATCH 25/42] Use r0 instead of 'unstable' for joined_members|rooms Dendrite is implementing these APIs and these APIs are already in the r0 spec, so we should be testing against r0 and not unstable. --- tests/30rooms/40joinedapis.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/30rooms/40joinedapis.pl b/tests/30rooms/40joinedapis.pl index 284326ca8..310a63de9 100644 --- a/tests/30rooms/40joinedapis.pl +++ b/tests/30rooms/40joinedapis.pl @@ -30,7 +30,7 @@ )->then( sub { do_request_json_for( $user, method => "GET", - uri => "/unstable/joined_rooms", + uri => "/r0/joined_rooms", ) })->then( sub { my ( $body ) = @_; @@ -92,7 +92,7 @@ do_request_json_for( $user, method => "GET", - uri => "/unstable/rooms/$room_id/joined_members", + uri => "/r0/rooms/$room_id/joined_members", )->then( sub { my ( $body ) = @_; From 7fa4fca21037ae85556cad5a36af5da6e398e8b0 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 18 Mar 2020 16:27:46 +0000 Subject: [PATCH 26/42] Missing bits --- tests/10apidoc/31room-state.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/10apidoc/31room-state.pl b/tests/10apidoc/31room-state.pl index 014d108f2..ae107d224 100644 --- a/tests/10apidoc/31room-state.pl +++ b/tests/10apidoc/31room-state.pl @@ -112,7 +112,7 @@ do_request_json_for( $user, method => "GET", - uri => "/unstable/rooms/$room_id/joined_members", + uri => "/r0/rooms/$room_id/joined_members", )->then( sub { my ( $body ) = @_; @@ -220,7 +220,7 @@ do_request_json_for( $user, method => "GET", - uri => "/unstable/joined_rooms", + uri => "/r0/joined_rooms", )->then( sub { my ( $body ) = @_; From 39f245519648919df3b6941c637f6b1c0fc4d54e Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 23 Mar 2020 15:22:16 -0400 Subject: [PATCH 27/42] Update NOT_FOUND error to BAD_ALIAS error to be spec compliant. (#837) --- tests/30rooms/05aliases.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index aacd69301..8234ef3bc 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -144,7 +144,7 @@ alias => $room_alias, alt_aliases => [ $bad_alias ], } - )->main::expect_matrix_error( 404, "M_NOT_FOUND" ) + )->main::expect_matrix_error( 400, "M_BAD_ALIAS" ) ->SyTest::pass_on_done( "m.room.canonical_alias rejects missing aliases" ); })->then( sub { # Create an invalid alias name (starts with % instead of #). From 07884c2ef5a8926f902b990e90bdc23bf7bf394d Mon Sep 17 00:00:00 2001 From: Naugrimm Date: Tue, 24 Mar 2020 12:59:10 +0100 Subject: [PATCH 28/42] fix the CAS login test (#829) see https://github.com/matrix-org/synapse/pull/6634 --- tests/12login/02cas.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/12login/02cas.pl b/tests/12login/02cas.pl index 824f0286c..56e7173bc 100644 --- a/tests/12login/02cas.pl +++ b/tests/12login/02cas.pl @@ -1,3 +1,5 @@ +use URI::Escape; + sub wait_for_cas_request { my ( $expected_path, %params ) = @_; @@ -109,12 +111,12 @@ sub wait_for_cas_request do => sub { my ( $http, $homeserver_info ) = @_; - my $HS_URI = $homeserver_info->client_location; - # the redirectUrl we send to /login/cas/redirect, which is where we # hope to get redirected back to my $REDIRECT_URL = "https://client?p=http%3A%2F%2Fserver"; + my $HS_URI = $homeserver_info->client_location . "/_matrix/client/r0/login/cas/ticket?redirectUrl=" . uri_escape($REDIRECT_URL); + # the ticket our mocked-up CAS server "generates" my $CAS_TICKET = "goldenticket"; From e6ca89416a05afccce825df304fd7b2b78457fca Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 30 Mar 2020 07:27:01 -0400 Subject: [PATCH 29/42] Add tests to ensure that the operation cannot be modified during interactive auth. (#830) --- tests/10apidoc/12device_management.pl | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tests/10apidoc/12device_management.pl b/tests/10apidoc/12device_management.pl index e9f35248d..2ce9ac87c 100644 --- a/tests/10apidoc/12device_management.pl +++ b/tests/10apidoc/12device_management.pl @@ -335,3 +335,61 @@ sub matrix_delete_device { matrix_delete_device( $user, $DEVICE_ID, undef ); })->main::expect_http_401; }; + + +test "The deleted device must be consistent through an interactive auth session", + requires => [ local_user_fixture( with_events => 0 ) ], + + do => sub { + my ( $user ) = @_; + + my $DEVICE_ID = "login_device"; + my $SECOND_DEVICE_ID = "second_device"; + + # Create two devices. + matrix_login_again_with_user( + $user, + device_id => $DEVICE_ID, + initial_device_display_name => "device display", + )->then( sub { + matrix_login_again_with_user( + $user, + device_id => $SECOND_DEVICE_ID, + initial_device_display_name => "device display", + ) + })->then( sub { + # Initiate the interactive authentication session with the first device. + matrix_delete_device( $user, $DEVICE_ID, {} ); + })->main::expect_http_401->then( sub { + my ( $resp ) = @_; + + my $body = decode_json $resp->content; + + log_if_fail( "Response to empty body", $body ); + + assert_json_keys( $body, qw( session params flows )); + + # Continue the interactive authentication session (by providing + # credentials), but attempt to delete the second device. + matrix_delete_device( $user, $SECOND_DEVICE_ID, { + auth => { + type => "m.login.password", + user => $user->user_id, + password => $user->password, + session => $body->{session}, + } + })->main::expect_http_403; + })->then( sub { + # The device delete was rejected (the device should still exist). + matrix_get_device( $user, $SECOND_DEVICE_ID ); + })->then( sub { + my ( $device ) = @_; + assert_json_keys( + $device, + qw( device_id user_id display_name ), + ); + assert_eq( $device->{device_id}, $SECOND_DEVICE_ID ); + assert_eq( $device->{display_name}, "device display" ); + Future->done( 1 ); + }); + }; From 6e732cbedcfd6ad4473edd12194505ee2159485b Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Mon, 30 Mar 2020 17:52:49 +0100 Subject: [PATCH 30/42] Add test for updating room aliases on upgraded room join (#844) --- tests/10apidoc/30room-create.pl | 31 ++++++++++++-- tests/10apidoc/33room-members.pl | 2 +- tests/30rooms/60version_upgrade.pl | 65 ++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/tests/10apidoc/30room-create.pl b/tests/10apidoc/30room-create.pl index b13bfd0e7..810bb259a 100644 --- a/tests/10apidoc/30room-create.pl +++ b/tests/10apidoc/30room-create.pl @@ -318,7 +318,7 @@ sub matrix_create_room }); } -push @EXPORT, qw( room_alias_name_fixture room_alias_fixture matrix_create_room_synced ); +push @EXPORT, qw( room_alias_name_fixture room_alias_fixture remote_room_alias_fixture matrix_create_room_synced ); my $next_alias_name = 0; @@ -356,7 +356,7 @@ sub room_alias_name_fixture =head2 room_alias_fixture - $fixture = room_alias_fixture( prefix => $prefix ) + $fixture = room_alias_fixture( prefix => $prefix, remote => 0 ) Returns a new Fixture, which when provisioned will allocate a name for a new room alias on the first homeserver, and return it as a string. Note that this @@ -366,6 +366,9 @@ =head2 room_alias_fixture An optional prefix string can be provided, which will be prepended onto the alias name. +An optional remote boolean can be supplied, which will generate an alias for +the second homeserver instead. + =cut sub room_alias_fixture @@ -374,7 +377,8 @@ sub room_alias_fixture return fixture( requires => [ - room_alias_name_fixture( prefix => $args{prefix} ), $main::HOMESERVER_INFO[0], + room_alias_name_fixture( prefix => $args{prefix} ), + $args{remote} ? $main::HOMESERVER_INFO[1] : $main::HOMESERVER_INFO[0], ], setup => sub { @@ -385,6 +389,27 @@ sub room_alias_fixture ); } +=head2 remote_room_alias_fixture + + $fixture = remote_room_alias_fixture( prefix => $prefix ) + +Returns a new Fixture, which when provisioned will allocate a name for a new +room alias on the second homeserver, and return it as a string. Note that this +does not actually create the alias on the server itself, it simply suggests a +new unique name for one. + +An optional prefix string can be provided, which will be prepended onto the +alias name. + +=cut + +sub remote_room_alias_fixture +{ + my %args = @_; + + return room_alias_fixture( prefix => $args{prefix}, remote => 1 ); +} + =head2 matrix_create_room_synced diff --git a/tests/10apidoc/33room-members.pl b/tests/10apidoc/33room-members.pl index 02066ede0..db4e86067 100644 --- a/tests/10apidoc/33room-members.pl +++ b/tests/10apidoc/33room-members.pl @@ -611,7 +611,7 @@ =head2 local_user_and_room_fixtures =item room_opts => HASH -Options to use when creating the room. Thes are passed into into +Options to use when creating the room. These are passed into C, whence they are passed on to the server. =back diff --git a/tests/30rooms/60version_upgrade.pl b/tests/30rooms/60version_upgrade.pl index f0fafd06d..6fa88605a 100644 --- a/tests/30rooms/60version_upgrade.pl +++ b/tests/30rooms/60version_upgrade.pl @@ -649,7 +649,6 @@ sub upgrade_room_synced { test "/upgrade moves aliases to the new room", requires => [ - $main::HOMESERVER_INFO[0], local_user_and_room_fixtures(), room_alias_fixture(), room_alias_fixture(), @@ -657,9 +656,8 @@ sub upgrade_room_synced { ], do => sub { - my ( $info, $creator, $room_id, $room_alias_1, $room_alias_2 ) = @_; + my ( $creator, $room_id, $room_alias_1, $room_alias_2 ) = @_; - my $server_name = $info->server_name; my $new_room_id; do_request_json_for( @@ -739,6 +737,67 @@ sub upgrade_room_synced { }); }; +test "/upgrade moves remote aliases to the new room", + requires => [ + local_user_and_room_fixtures(), + remote_user_fixture(), + remote_room_alias_fixture(), + qw( can_upgrade_room_version ), + ], + + do => sub { + my ( $creator, $room_id, $remote_user, $remote_room_alias ) = @_; + + my $new_room_id; + + log_if_fail $room_id; + + # Invite the remote user to our room + matrix_invite_user_to_room( + $creator, $remote_user, $room_id + )->then( sub { + # Have the remote user join the room + matrix_join_room( $remote_user, $room_id ); + })->then( sub { + # Have the remote user add an alias + do_request_json_for( + $remote_user, + method => "PUT", + uri => "/r0/directory/room/$remote_room_alias", + content => { room_id => $room_id }, + ); + })->then( sub { + # Upgrade the room + upgrade_room_synced( + $creator, $room_id, + new_version => $TEST_NEW_VERSION, + ); + })->then( sub { + ( $new_room_id ) = @_; + + # Invite the remote user to the new room + matrix_invite_user_to_room( + $creator, $remote_user, $new_room_id + ); + })->then( sub { + # Have the remote user join the upgraded room + matrix_join_room( $remote_user, $new_room_id ); + })->then( sub { + # Check that the remote alias points to the new room id + do_request_json_for( + $remote_user, + method => "GET", + uri => "/r0/directory/room/$remote_room_alias", + ); + })->then( sub { + my ( $body ) = @_; + + assert_eq( $body->{room_id}, $new_room_id, "room_id for remote alias" ); + + Future->done(1); + }); + }; + test "/upgrade preserves direct room state", requires => [ local_user_and_room_fixtures(), From e207619b77f95f20f96a4d0bdf5446f113c9a36b Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Thu, 2 Apr 2020 21:28:02 +0200 Subject: [PATCH 31/42] Add more logging to "Guest user can set display names" (#846) --- tests/30rooms/13guestaccess.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/30rooms/13guestaccess.pl b/tests/30rooms/13guestaccess.pl index 89a03e4a6..f5480bc35 100644 --- a/tests/30rooms/13guestaccess.pl +++ b/tests/30rooms/13guestaccess.pl @@ -172,13 +172,19 @@ displayname => "creeper", }, )})->then( sub { + my $iter = 0; + retry_until_success { + $iter++; + Future->needs_all( do_request_json_for( $guest_user, method => "GET", uri => $displayname_uri, )->then( sub { my ( $body ) = @_; + log_if_fail "Iteration $iter: /displayname result", $body; + assert_eq( $body->{displayname}, "creeper", "Profile displayname" ); Future->done(1); @@ -188,6 +194,8 @@ uri => "/r0/rooms/$room_id/state/m.room.member/:user_id", )->then( sub { my ( $body ) = @_; + log_if_fail "Iteration $iter: /state result", $body; + assert_eq( $body->{displayname}, "creeper", "Room displayname" ); Future->done(1); From 30116adc31d206327f2b97b620d7bea4d808c350 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Mon, 6 Apr 2020 12:35:04 +0100 Subject: [PATCH 32/42] Add test for querying remote public rooms list with local server_name (#847) --- tests/30rooms/70publicroomslist.pl | 54 +++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/tests/30rooms/70publicroomslist.pl b/tests/30rooms/70publicroomslist.pl index 165d47a83..4ce4e5785 100644 --- a/tests/30rooms/70publicroomslist.pl +++ b/tests/30rooms/70publicroomslist.pl @@ -263,7 +263,59 @@ content => { filter => { - generic_search_term => "wombles", # Search case insesitively + generic_search_term => "wombles", # Search case insensitively + } + }, + )->then( sub { + my ( $body ) = @_; + + log_if_fail "Body", $body; + + assert_json_keys( $body, qw( chunk ) ); + + # We only expect to find a single result + assert_eq( scalar @{ $body->{chunk} }, 1 ); + assert_eq( $body->{chunk}[0]{room_id}, $room_id ); + + Future->done( 1 ); + })->on_fail( sub { + my ( $exc ) = @_; + chomp $exc; + log_if_fail "Failed to search room dir: $exc"; + }); + } + }) + }; + +test "Asking for a remote rooms list, but supplying the local server's name, returns the local rooms list", + requires => [ local_user_fixture() ], + + check => sub { + my ( $local_user ) = @_; + + my $room_id; + + matrix_create_room( $local_user, + visibility => "public", + name => "Test Name", + topic => "Test Topic Wibbles", + )->then( sub { + ( $room_id ) = @_; + + retry_until_success { + do_request_json_for( $local_user, + method => "POST", + uri => "/r0/publicRooms", + + # Ask the local server for a remote room list, but supply the local server's server_name + # Server should return the local public rooms list + params => { + server => $local_user->server_name, + }, + + content => { + filter => { + generic_search_term => "wibbles", # Search case insensitively } }, )->then( sub { From fbc3c4a2bd71fc496f31b5eb2df57081409fcfaa Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 8 Apr 2020 11:31:43 +0100 Subject: [PATCH 33/42] Update dendrite docs with new whitelist/blacklist info (#849) --- docs/dendrite-setup.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/dendrite-setup.md b/docs/dendrite-setup.md index 6a6a129e3..38036838b 100644 --- a/docs/dendrite-setup.md +++ b/docs/dendrite-setup.md @@ -41,14 +41,18 @@ SyTest will expect Dendrite to be at `../dendrite` relative to Sytest's root dir Simply run the following to execute tests: ``` -./run-tests.pl -I Dendrite::Monolith -W ../dendrite/testfile +./run-tests.pl -I Dendrite::Monolith -W ../dendrite/sytest-whitelist -B ../dendrite/sytest-blacklist ``` ## Useful flags * `-W` applies a test whitelist file, one of which is currently kept up to date with what sytests Dendrite passes - [here](https://github.com/matrix-org/dendrite/blob/master/testfile) + [here](https://github.com/matrix-org/dendrite/blob/master/sytest-whitelist) + +* `-B` applies a test blacklist file, one of which is currently kept up to date + with what sytests are currently flaky (fail *sometimes*) with Dendrite + [here](https://github.com/matrix-org/dendrite/blob/master/sytest-blacklist) * `-d` lets you set the path to Dendrite's `bin/` directory, in case it's somewhere other than `../dendrite/bin` From e2ce53f24406484c61779da26be958b2148c972c Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 9 Apr 2020 13:54:51 +0100 Subject: [PATCH 34/42] Change room_fixture to run matrix_create_room_synced by default (#848) --- tests/10apidoc/33room-members.pl | 16 +++++++++++++++- tests/30rooms/01state.pl | 4 +++- tests/50federation/33room-get-missing-events.pl | 4 +++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/10apidoc/33room-members.pl b/tests/10apidoc/33room-members.pl index db4e86067..12339f002 100644 --- a/tests/10apidoc/33room-members.pl +++ b/tests/10apidoc/33room-members.pl @@ -512,6 +512,11 @@ =head2 room_fixture C<$user_fixture> should be a Fixture which will provide a User when provisioned. +C can contain a boolean key called C, which determines whether to +perform a user /sync request after creating the room. This involves inserting +and checking for a 'm.room.test' event in the room state, which may be +undesirable in some cases. Defaults to 1. + Any other options are passed into C, whence they are passed on to the server. @@ -531,7 +536,16 @@ sub room_fixture setup => sub { my ( $user ) = @_; - matrix_create_room( $user, %args )->then( sub { + # Determine whether to create room synced or not. Default is synced + # + # This will insert a m.room.test event into room state which + # some tests may not want + my $sync = 1; + if ( exists( $args{synced} ) && $args{synced} == 0 ) { + $sync = 0; + } + + ( $sync ? matrix_create_room_synced( $user, %args ) : matrix_create_room( $user, %args ) )->then( sub { my ( $room_id ) = @_; # matrix_create_room returns the room_id and the room_alias if # one was set. However we only want to return the room_id diff --git a/tests/30rooms/01state.pl b/tests/30rooms/01state.pl index 9e8f8c13c..f07b16bb9 100644 --- a/tests/30rooms/01state.pl +++ b/tests/30rooms/01state.pl @@ -263,7 +263,9 @@ sub set_test_state } test "Setting state twice is idempotent", - requires => [ local_user_and_room_fixtures() ], + # Setting synced to 1 inserts a m.room.test object into the + # timeline which this test does not expect + requires => [ local_user_and_room_fixtures( room_opts => { synced => 0 } ) ], check => sub { my ( $user, $room_id ) = @_; diff --git a/tests/50federation/33room-get-missing-events.pl b/tests/50federation/33room-get-missing-events.pl index 2156b4cd2..589f2b8d1 100644 --- a/tests/50federation/33room-get-missing-events.pl +++ b/tests/50federation/33room-get-missing-events.pl @@ -105,7 +105,9 @@ foreach my $vis (qw( world_readable shared invite joined )) { test "Inbound federation can return missing events for $vis visibility", requires => [ $main::OUTBOUND_CLIENT, - local_user_and_room_fixtures(), + # Setting synced to 1 inserts a m.room.test object into the + # timeline which this test does not expect + local_user_and_room_fixtures( room_opts => { synced => 0 } ), federation_user_id_fixture() ], do => sub { From a73554a98581af643c9cd8d244eeca17dcc103ce Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 14 Apr 2020 18:20:36 +0100 Subject: [PATCH 35/42] Small comment fixes for consistency (#808) --- tests/30rooms/12thirdpartyinvite.pl | 2 +- tests/41end-to-end-keys/06-device-lists.pl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/30rooms/12thirdpartyinvite.pl b/tests/30rooms/12thirdpartyinvite.pl index cbaa0c4c0..2b68b672c 100644 --- a/tests/30rooms/12thirdpartyinvite.pl +++ b/tests/30rooms/12thirdpartyinvite.pl @@ -190,7 +190,7 @@ matrix_create_and_join_room( [ $creator, $inviter ], visibility => "private", - preset => "private_chat", + preset => "private_chat", # Allow default PL users to invite others with_invite => 1, )->then( sub { my ( $room_id ) = @_; diff --git a/tests/41end-to-end-keys/06-device-lists.pl b/tests/41end-to-end-keys/06-device-lists.pl index 4ed3b77e0..62ec4e1d3 100644 --- a/tests/41end-to-end-keys/06-device-lists.pl +++ b/tests/41end-to-end-keys/06-device-lists.pl @@ -731,8 +731,7 @@ sub sync_until_user_in_device_list matrix_create_room( $creator, invite => [ $remote_user->user_id ], - # Allow default PL users to invite others - preset => "private_chat", + preset => "private_chat", # Allow default PL users to invite others )->then( sub { ( $room_id ) = @_; From 034199da24c60014751503a059fe1ea7ac757381 Mon Sep 17 00:00:00 2001 From: Alex Chen Date: Wed, 15 Apr 2020 03:00:52 +0800 Subject: [PATCH 36/42] Make message history pagination test less flaky (#851) * Make message history pagination test less flaky * Use await_sync_timeline_contains --- tests/30rooms/04messages.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/30rooms/04messages.pl b/tests/30rooms/04messages.pl index 9a267a515..2eac89727 100644 --- a/tests/30rooms/04messages.pl +++ b/tests/30rooms/04messages.pl @@ -215,6 +215,15 @@ body => "Message number $_[0]" ) } foreach => [ 1 .. 20 ] )->then( sub { + await_sync_timeline_contains( + $user, $room_id, check => sub { + any { + $_->{type} eq "m.room.message" + && $_->{content}{body} eq "Message number 20" + } @_; + }, + ); + })->then( sub { matrix_get_room_messages( $user, $room_id, limit => 5 ) })->then( sub { my ( $body ) = @_; From 2c8a31240086880148cdd7ec95aaaa36c50b12a5 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 15 Apr 2020 10:02:47 +0100 Subject: [PATCH 37/42] Modify login tests to be spec compliant The 'identifier' key is required as per: https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login Synapse likely falls back to previous logic if this key is missing but Dendrite will just fail, correctly stating that the identifier key is missing. --- tests/10apidoc/02login.pl | 30 ++++++++++++++++++++++++------ tests/14account/02deactivate.pl | 5 ++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/tests/10apidoc/02login.pl b/tests/10apidoc/02login.pl index 2c9dc9c6f..516cb3de3 100644 --- a/tests/10apidoc/02login.pl +++ b/tests/10apidoc/02login.pl @@ -82,7 +82,10 @@ content => { type => "m.login.password", - user => $user_id, + identifier => { + type => "m.id.user", + user => $user_id, + }, password => $password, }, )->then( sub { @@ -114,7 +117,10 @@ content => { type => "m.login.password", - user => $user_id, + identifier => { + type => "m.id.user", + user => $user_id, + }, password => $password, device_id => $device_id, }, @@ -146,7 +152,10 @@ content => { type => "m.login.password", - user => $user_localpart, + identifier => { + type => "m.id.user", + user => $user_localpart, + }, password => $password, }, )->then( sub { @@ -174,7 +183,10 @@ content => { type => "m.login.password", - user => "i-ought-not-to-exist", + identifier => { + type => "m.id.user", + user => "i-ought-not-to-exist", + }, password => "XXX", }, )->main::expect_http_403; @@ -193,7 +205,10 @@ content => { type => "m.login.password", - user => $user_id, + identifier => { + type => "m.id.user", + user => $user_id, + }, password => "${password}wrong", }, )->main::expect_http_403->then( sub { @@ -225,7 +240,10 @@ sub matrix_login_again_with_user uri => "/r0/login", content => { type => "m.login.password", - user => $user->user_id, + identifier => { + type => "m.id.user", + user => $user->user_id, + }, password => $user->password, %args, }, diff --git a/tests/14account/02deactivate.pl b/tests/14account/02deactivate.pl index 3ff5baa79..20b03d6be 100644 --- a/tests/14account/02deactivate.pl +++ b/tests/14account/02deactivate.pl @@ -67,7 +67,10 @@ sub matrix_deactivate_account uri => "/r0/login", content => { type => "m.login.password", - user => $user->user_id, + identifier => { + type => "m.id.user", + user => $user->user_id, + }, password => $user->password, } # We don't mandate the exact failure code here From a22ca2dd35cb28630937c4acb566f5e73981f8ee Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 17 Apr 2020 07:57:18 -0400 Subject: [PATCH 38/42] Add tests for SSO + user interactive authentication. (#845) --- tests/10apidoc/12device_management.pl | 76 +------ tests/10apidoc/13ui-auth.pl | 274 ++++++++++++++++++++++++++ tests/12login/02cas.pl | 23 +-- tests/30rooms/05aliases.pl | 2 +- 4 files changed, 286 insertions(+), 89 deletions(-) create mode 100644 tests/10apidoc/13ui-auth.pl diff --git a/tests/10apidoc/12device_management.pl b/tests/10apidoc/12device_management.pl index 2ce9ac87c..88b0e8ce4 100644 --- a/tests/10apidoc/12device_management.pl +++ b/tests/10apidoc/12device_management.pl @@ -37,7 +37,7 @@ sub matrix_delete_device { } test "GET /device/{deviceId}", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -64,7 +64,7 @@ sub matrix_delete_device { }; test "GET /device/{deviceId} gives a 404 for unknown devices", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -78,7 +78,7 @@ sub matrix_delete_device { test "GET /devices", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -136,7 +136,7 @@ sub matrix_delete_device { }; test "PUT /device/{deviceId} updates device fields", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -172,7 +172,7 @@ sub matrix_delete_device { }; test "PUT /device/{deviceId} gives a 404 for unknown devices", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -188,7 +188,7 @@ sub matrix_delete_device { }; test "DELETE /device/{deviceId}", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -273,8 +273,8 @@ sub matrix_delete_device { # test "DELETE /device/{deviceId} requires UI auth user to match device owner", requires => [ - local_user_fixture( with_events => 0 ), - local_user_fixture( with_events => 0 ), + local_user_fixture(), + local_user_fixture(), ], do => sub { @@ -317,7 +317,7 @@ sub matrix_delete_device { test "DELETE /device/{deviceId} with no body gives a 401", - requires => [ local_user_fixture( with_events => 0 ) ], + requires => [ local_user_fixture() ], do => sub { my ( $user ) = @_; @@ -335,61 +335,3 @@ sub matrix_delete_device { matrix_delete_device( $user, $DEVICE_ID, undef ); })->main::expect_http_401; }; - - -test "The deleted device must be consistent through an interactive auth session", - requires => [ local_user_fixture( with_events => 0 ) ], - - do => sub { - my ( $user ) = @_; - - my $DEVICE_ID = "login_device"; - my $SECOND_DEVICE_ID = "second_device"; - - # Create two devices. - matrix_login_again_with_user( - $user, - device_id => $DEVICE_ID, - initial_device_display_name => "device display", - )->then( sub { - matrix_login_again_with_user( - $user, - device_id => $SECOND_DEVICE_ID, - initial_device_display_name => "device display", - ) - })->then( sub { - # Initiate the interactive authentication session with the first device. - matrix_delete_device( $user, $DEVICE_ID, {} ); - })->main::expect_http_401->then( sub { - my ( $resp ) = @_; - - my $body = decode_json $resp->content; - - log_if_fail( "Response to empty body", $body ); - - assert_json_keys( $body, qw( session params flows )); - - # Continue the interactive authentication session (by providing - # credentials), but attempt to delete the second device. - matrix_delete_device( $user, $SECOND_DEVICE_ID, { - auth => { - type => "m.login.password", - user => $user->user_id, - password => $user->password, - session => $body->{session}, - } - })->main::expect_http_403; - })->then( sub { - # The device delete was rejected (the device should still exist). - matrix_get_device( $user, $SECOND_DEVICE_ID ); - })->then( sub { - my ( $device ) = @_; - assert_json_keys( - $device, - qw( device_id user_id display_name ), - ); - assert_eq( $device->{device_id}, $SECOND_DEVICE_ID ); - assert_eq( $device->{display_name}, "device display" ); - Future->done( 1 ); - }); - }; diff --git a/tests/10apidoc/13ui-auth.pl b/tests/10apidoc/13ui-auth.pl new file mode 100644 index 000000000..40d831a79 --- /dev/null +++ b/tests/10apidoc/13ui-auth.pl @@ -0,0 +1,274 @@ +use JSON qw( decode_json ); +use URI::Escape; + +our @EXPORT = qw( wait_for_cas_request ); + +# A convenience function which wraps await_http_request. It returns a successful +# CAS response when queried for a particular path. +# +# This takes two parameters: +# * The expected path of the request the homeserver makes to the CAS server. +# * A hash of parameters with the following (optional) keys: +# * response: The HTTP response body to return to the homeserver request. +sub wait_for_cas_request +{ + my ( $expected_path, %params ) = @_; + + await_http_request( $expected_path, sub { + return 1; + })->then( sub { + my ( $request ) = @_; + + my $response = HTTP::Response->new( 200 ); + $response->add_content( $params{response} // "" ); + $response->content_type( "text/plain" ); + $response->content_length( length $response->content ); + $request->respond( $response ); + + Future->done( $request ); + }); +} + +# Generate a ticket-submission request from the client to the homeserver. +# +# Waits for the validation request from the homeserver, and returns the given response. +sub make_ticket_request +{ + my ( $http, $homeserver_info, $session, $ticket, $response ) = @_; + + # Note that we skip almost all of the CAS flow since it isn't important + # for this test. The user just needs to end up back at the homeserver + # with a valid ticket (and the original UI Auth session ID). + my $login_uri = $homeserver_info->client_location . "/_matrix/client/r0/login/cas/ticket?session=$session&ticket=$ticket"; + + Future->needs_all( + wait_for_cas_request( + "/cas/proxyValidate", + response => $response, + ), + $http->do_request_json( + method => "GET", + full_uri => $login_uri, + max_redirects => 0, # don't follow the redirect + ), + ); +} + +test "Interactive authentication types include SSO", + requires => [ local_user_fixture() ], + + do => sub { + my ( $user ) = @_; + + my $DEVICE_ID = "login_device"; + + matrix_login_again_with_user( + $user, + device_id => $DEVICE_ID, + initial_device_display_name => "device display", + )->then( sub { + # Initiate the interactive authentication session. + matrix_delete_device( $user, $DEVICE_ID, {} ); + })->main::expect_http_401->then( sub { + my ($resp) = @_; + + my $body = decode_json $resp->content; + + log_if_fail "Response to empty body", $body; + + assert_json_keys($body, qw(session params flows)); + assert_json_list $body->{flows}; + + # Note that this uses the unstable value. + die "org.matrix.login.sso was not listed" unless + any { $_->{stages}[0] eq "org.matrix.login.sso" } @{ $body->{flows} }; + + Future->done( 1 ); + }); + }; + +test "Can perform interactive authentication with SSO", + requires => [ + local_user_fixture(), + $main::API_CLIENTS[0], + $main::HOMESERVER_INFO[0], + ], + + do => sub { + my ( $user, $http, $homeserver_info ) = @_; + + my $DEVICE_ID = "login_device"; + + my ($user_localpart) = $user->user_id =~ m/@([^:]*):/; + my $CAS_SUCCESS = <<"EOF"; + + + $user_localpart + + + +EOF + + # the ticket our mocked-up CAS server "generates" + my $CAS_TICKET = "goldenticket"; + my $session; + + # Create a device. + matrix_login_again_with_user( + $user, + device_id => $DEVICE_ID, + initial_device_display_name => "device display", + )->then( sub { + # Initiate the interactive authentication session via device deletion. + matrix_delete_device( $user, $DEVICE_ID, {} ); + })->main::expect_http_401->then( sub { + my ( $resp ) = @_; + + my $body = decode_json $resp->content; + + log_if_fail "Response to empty body", $body; + + assert_json_keys( $body, qw( session params flows )); + + $session = $body->{session}; + + make_ticket_request( $http, $homeserver_info, $session, $CAS_TICKET, $CAS_SUCCESS ); + })->then( sub { + # Repeat the device deletion, which should now complete. + matrix_delete_device( $user, $DEVICE_ID, { + auth => { + session => $session, + }, + }); + })->then( sub { + # the device should be deleted. + matrix_get_device( $user, $DEVICE_ID )->main::expect_http_404; + }); + }; + +test "The user must be consistent through an interactive authentication session with SSO", + requires => [ + local_user_fixture(), + $main::API_CLIENTS[0], + $main::HOMESERVER_INFO[0], + ], + + do => sub { + my ( $user, $http, $homeserver_info ) = @_; + + my $DEVICE_ID = "login_device"; + + # The user below is what is returned from SSO and does not match the user + # being logged into the homeserver. + my $CAS_SUCCESS = <<'EOF'; + + + cas_user + + + +EOF + + # the ticket our mocked-up CAS server "generates" + my $CAS_TICKET = "goldenticket"; + my $session; + + # Create a device. + matrix_login_again_with_user( + $user, + device_id => $DEVICE_ID, + initial_device_display_name => "device display", + )->then( sub { + # Initiate the interactive authentication session via device deletion. + matrix_delete_device( $user, $DEVICE_ID, {} ); + })->main::expect_http_401->then( sub { + my ( $resp ) = @_; + + my $body = decode_json $resp->content; + + log_if_fail "Response to empty body", $body; + + assert_json_keys( $body, qw( session params flows )); + + $session = $body->{session}; + + make_ticket_request( $http, $homeserver_info, $session, $CAS_TICKET, $CAS_SUCCESS ); + })->then( sub { + # Repeat the device deletion, which should now give an auth error. + matrix_delete_device( $user, $DEVICE_ID, { + auth => { + session => $session, + }, + })->main::expect_http_403; + })->then( sub { + # The device delete was rejected (the device should still exist). + matrix_get_device( $user, $DEVICE_ID ); + })->then( sub { + my ( $device ) = @_; + assert_json_keys( + $device, + qw( device_id user_id display_name ), + ); + assert_eq( $device->{device_id}, $DEVICE_ID ); + assert_eq( $device->{display_name}, "device display" ); + Future->done( 1 ); + }); + }; + + +test "The operation must be consistent through an interactive authentication session", + requires => [ local_user_fixture() ], + + do => sub { + my ( $user ) = @_; + + my $DEVICE_ID = "login_device"; + my $SECOND_DEVICE_ID = "second_device"; + + # Create two devices. + matrix_login_again_with_user( + $user, + device_id => $DEVICE_ID, + initial_device_display_name => "device display", + )->then( sub { + matrix_login_again_with_user( + $user, + device_id => $SECOND_DEVICE_ID, + initial_device_display_name => "device display", + ) + })->then( sub { + # Initiate the interactive authentication session with the first device. + matrix_delete_device( $user, $DEVICE_ID, {} ); + })->main::expect_http_401->then( sub { + my ( $resp ) = @_; + + my $body = decode_json $resp->content; + + log_if_fail "Response to empty body", $body; + + assert_json_keys( $body, qw( session params flows )); + + # Continue the interactive authentication session (by providing + # credentials), but attempt to delete the second device. + matrix_delete_device( $user, $SECOND_DEVICE_ID, { + auth => { + type => "m.login.password", + user => $user->user_id, + password => $user->password, + session => $body->{session}, + } + })->main::expect_http_403; + })->then( sub { + # The device delete was rejected (the device should still exist). + matrix_get_device( $user, $SECOND_DEVICE_ID ); + })->then( sub { + my ( $device ) = @_; + assert_json_keys( + $device, + qw( device_id user_id display_name ), + ); + assert_eq( $device->{device_id}, $SECOND_DEVICE_ID ); + assert_eq( $device->{display_name}, "device display" ); + Future->done( 1 ); + }); + }; diff --git a/tests/12login/02cas.pl b/tests/12login/02cas.pl index 56e7173bc..429c63b5d 100644 --- a/tests/12login/02cas.pl +++ b/tests/12login/02cas.pl @@ -1,24 +1,5 @@ use URI::Escape; -sub wait_for_cas_request -{ - my ( $expected_path, %params ) = @_; - - await_http_request( $expected_path, sub { - return 1; - })->then( sub { - my ( $request ) = @_; - - my $response = HTTP::Response->new( 200 ); - $response->add_content( $params{response} // "" ); - $response->content_type( "text/plain" ); - $response->content_length( length $response->content ); - $request->respond( $response ); - - Future->done( $request ); - }); -} - my $CAS_SUCCESS = <<'EOF'; @@ -41,7 +22,7 @@ sub wait_for_cas_request my ( $body ) = @_; assert_json_keys( $body, qw( flows )); - ref $body->{flows} eq "ARRAY" or die "Expected 'flows' as a list"; + assert_json_list $body->{flows}; die "m.login.sso was not listed" unless any { $_->{type} eq "m.login.sso" } @{ $body->{flows} }; @@ -64,7 +45,7 @@ sub wait_for_cas_request my ( $body ) = @_; assert_json_keys( $body, qw( flows )); - ref $body->{flows} eq "ARRAY" or die "Expected 'flows' as a list"; + assert_json_list $body->{flows}; die "SKIP: no m.login.cas" unless any { $_->{type} eq "m.login.cas" } @{ $body->{flows} }; diff --git a/tests/30rooms/05aliases.pl b/tests/30rooms/05aliases.pl index 8234ef3bc..2f3cb5bf2 100644 --- a/tests/30rooms/05aliases.pl +++ b/tests/30rooms/05aliases.pl @@ -345,7 +345,7 @@ sub _test_can_create_and_delete_alias { }; test "Can delete canonical alias", - requires => [ local_user_fixture( with_events => 0 ), room_alias_fixture(), + requires => [ local_user_fixture(), room_alias_fixture(), qw( can_create_room_alias )], do => sub { From d1b97e84e14d88a7a4a6c5bdb75753cd35d0b43f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 20 Apr 2020 21:02:19 +0100 Subject: [PATCH 39/42] Test that users receive updates for their own devices (#854) --- tests/41end-to-end-keys/06-device-lists.pl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/41end-to-end-keys/06-device-lists.pl b/tests/41end-to-end-keys/06-device-lists.pl index 4ed3b77e0..d5b90e8f4 100644 --- a/tests/41end-to-end-keys/06-device-lists.pl +++ b/tests/41end-to-end-keys/06-device-lists.pl @@ -788,3 +788,17 @@ sub sync_until_user_in_device_list Future->done(1); }); }; + +# regression test for https://github.com/matrix-org/synapse/pull/7160 +test "Users receive device_list updates for their own devices", + requires => [ local_user_fixture(), qw( can_sync ) ], + + check => sub { + my ( $user1 ) = @_; + + matrix_sync( $user1 )->then( sub { + matrix_login_again_with_user( $user1 ); + })->then( sub { + sync_until_user_in_device_list( $user1, $user1 ); + }); + }; From 2d2fbbb20f12bf3c7b8999c09d4400a6dfb6ede6 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 21 Apr 2020 11:04:48 +0100 Subject: [PATCH 40/42] route GET account_data requests to client_reader (#855) tests for https://github.com/matrix-org/synapse/pull/7311 --- lib/SyTest/Homeserver/Synapse.pm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/SyTest/Homeserver/Synapse.pm b/lib/SyTest/Homeserver/Synapse.pm index 1d2d9d18d..2e42d29e0 100644 --- a/lib/SyTest/Homeserver/Synapse.pm +++ b/lib/SyTest/Homeserver/Synapse.pm @@ -1226,10 +1226,13 @@ EOCONFIG sub generate_haproxy_get_map { return <<'EOCONFIG'; -^/_matrix/federation/v1/groups/ federation_reader - -^/_matrix/client/(api/v1|r0|unstable)/groups/ client_reader +# pushrules should be here, but the tests seem to be racy. +# ^/_matrix/client/(api/v1|r0|unstable)/pushrules/ client_reader +^/_matrix/client/(api/v1|r0|unstable)/groups/ client_reader +^/_matrix/client/r0/user/[^/]*/account_data/ client_reader +^/_matrix/client/r0/user/[^/]*/rooms/[^/]*/account_data/ client_reader +^/_matrix/federation/v1/groups/ federation_reader EOCONFIG } From 394ee6024e0658045043b65454a5384e6baaaf67 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Wed, 22 Apr 2020 15:02:35 +0100 Subject: [PATCH 41/42] Add support for running worker mode against redis (#857) --- lib/SyTest/Homeserver/Synapse.pm | 7 +++++++ lib/SyTest/HomeserverFactory/Synapse.pm | 6 +++++- scripts/synapse_sytest.sh | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/SyTest/Homeserver/Synapse.pm b/lib/SyTest/Homeserver/Synapse.pm index 1d2d9d18d..023cafee1 100644 --- a/lib/SyTest/Homeserver/Synapse.pm +++ b/lib/SyTest/Homeserver/Synapse.pm @@ -33,6 +33,7 @@ sub _init $self->{paths} = {}; $self->{dendron} = ''; + $self->{redis_host} = ''; $self->SUPER::_init( $args ); @@ -282,6 +283,11 @@ sub start limit_usage_by_mau => "true", max_mau_value => 50000000, + redis => { + enabled => $self->{redis_host} ne '', + host => $self->{redis_host}, + }, + map { defined $self->{$_} ? ( $_ => $self->{$_} ) : () } qw( @@ -653,6 +659,7 @@ sub _init $self->SUPER::_init( @_ ); $self->{dendron} = delete $args->{dendron_binary}; + $self->{redis_host} = delete $args->{redis_host}; if( my $level = delete $args->{torture_replication} ) { # torture the replication protocol a bit, to replicate bugs. diff --git a/lib/SyTest/HomeserverFactory/Synapse.pm b/lib/SyTest/HomeserverFactory/Synapse.pm index 5849e584f..49a75c7af 100644 --- a/lib/SyTest/HomeserverFactory/Synapse.pm +++ b/lib/SyTest/HomeserverFactory/Synapse.pm @@ -101,6 +101,7 @@ sub _init $self->{impl} = "SyTest::Homeserver::Synapse::ViaDendron"; $self->{args}{dendron_binary} = ""; $self->{args}{torture_replication} = 0; + $self->{args}{redis_host} = ""; } sub get_options @@ -108,8 +109,9 @@ sub get_options my $self = shift; return ( - 'dendron-binary=s' => \$self->{args}{dendron_binary}, + 'dendron-binary=s' => \$self->{args}{dendron_binary}, 'torture-replication:50' => \$self->{args}{torture_replication}, + 'redis-host=s' => \$self->{args}{redis_host}, $self->SUPER::get_options(), ); } @@ -125,6 +127,8 @@ sub print_usage --dendron-binary PATH - path to the 'dendron' binary --torture-replication[=LEVEL] - enable torturing of the replication protocol + + --redis-host HOST - if set then use redis for replication EOF } diff --git a/scripts/synapse_sytest.sh b/scripts/synapse_sytest.sh index d13c8b2d1..599e4392a 100755 --- a/scripts/synapse_sytest.sh +++ b/scripts/synapse_sytest.sh @@ -121,7 +121,7 @@ if [ -n "$OFFLINE" ]; then else # We've already created the virtualenv, but lets double check we have all # deps. - /venv/bin/pip install -q --upgrade --no-cache-dir /src + /venv/bin/pip install -q --upgrade --no-cache-dir /src[redis] /venv/bin/pip install -q --upgrade --no-cache-dir \ lxml psycopg2 coverage codecov tap.py coverage_enable_subprocess From 35e5731828f241d3f1458354b2a6ab05d545b5fb Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 23 Apr 2020 13:51:55 +0100 Subject: [PATCH 42/42] Fix OFFLINE support for the sytest-synapse docker image (#858) The sytest-synapse docker image is meant to support an OFFLINE mode, but this doesn't currently work terribly well (when run against a readonly synapse, it complains about readonly filesystem). This change fixes it by installing synapse with `pip` instead of trying to run `setup.py` directly. --- scripts/synapse_sytest.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/synapse_sytest.sh b/scripts/synapse_sytest.sh index 599e4392a..7792ecd41 100755 --- a/scripts/synapse_sytest.sh +++ b/scripts/synapse_sytest.sh @@ -114,10 +114,11 @@ if [ -n "$OFFLINE" ]; then # if we're in offline mode, just put synapse into the virtualenv, and # hope that the deps are up-to-date. # - # (`pip install -e` likes to reinstall setuptools even if it's already installed, - # so we just run setup.py explicitly.) - # - (cd /src && /venv/bin/python setup.py -q develop) + # --no-use-pep517 works around what appears to be a pip issue + # (https://github.com/pypa/pip/issues/5402 possibly) where pip wants + # to reinstall any requirements for the build system, even if they are + # already installed. + /venv/bin/pip install --no-index --no-use-pep517 /src else # We've already created the virtualenv, but lets double check we have all # deps.