diff --git a/build.sh b/build.sh index eed4d52f5..9a8050f3c 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,3 @@ -#!/bin/bash +#!/bin/sh GOBIN=$PWD/`dirname $0`/bin go install -v ./cmd/... diff --git a/docs/sytest.md b/docs/sytest.md index 99987fea5..e936dc493 100644 --- a/docs/sytest.md +++ b/docs/sytest.md @@ -59,7 +59,7 @@ Once the tests are complete, run the helper script to see if you need to add any newly passing test names to `testfile` in the project's root directory: ```sh -../dendrite/show-expected-fail-tests.sh results.tap +../dendrite/show-expected-fail-tests.sh results.tap ../dendrite/testfile ``` If the script prints nothing/exits with 0, then you're good to go. diff --git a/federationapi/routing/state.go b/federationapi/routing/state.go index 58398bde9..86cf1cf54 100644 --- a/federationapi/routing/state.go +++ b/federationapi/routing/state.go @@ -103,6 +103,10 @@ func getState( return nil, resErr } + if event.RoomID() != roomID { + return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil} + } + prevEventIDs := getIDsFromEventRef(event.PrevEvents()) authEventIDs := getIDsFromEventRef(event.AuthEvents()) diff --git a/roomserver/alias/alias.go b/roomserver/alias/alias.go index 27279aad8..6a34aacdd 100644 --- a/roomserver/alias/alias.go +++ b/roomserver/alias/alias.go @@ -96,12 +96,21 @@ func (r *RoomserverAliasAPI) GetRoomIDForAlias( return err } - // No rooms found locally, try our application services by making a call to - // the appservice component - aliasReq := appserviceAPI.RoomAliasExistsRequest{Alias: request.Alias} - var aliasResp appserviceAPI.RoomAliasExistsResponse - if err = r.AppserviceAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil { - return err + if roomID == "" { + // No room found locally, try our application services by making a call to + // the appservice component + aliasReq := appserviceAPI.RoomAliasExistsRequest{Alias: request.Alias} + var aliasResp appserviceAPI.RoomAliasExistsResponse + if err = r.AppserviceAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil { + return err + } + + if aliasResp.AliasExists { + roomID, err = r.DB.GetRoomIDForAlias(ctx, request.Alias) + if err != nil { + return err + } + } } response.RoomID = roomID diff --git a/roomserver/alias/alias_test.go b/roomserver/alias/alias_test.go new file mode 100644 index 000000000..4b9ca022d --- /dev/null +++ b/roomserver/alias/alias_test.go @@ -0,0 +1,196 @@ +// Copyright 2019 Serra Allgood +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package alias + +import ( + "context" + "fmt" + "strings" + "testing" + + appserviceAPI "github.com/matrix-org/dendrite/appservice/api" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" +) + +type MockRoomserverAliasAPIDatabase struct { + mode string + attempts int +} + +// These methods can be essentially noop +func (db MockRoomserverAliasAPIDatabase) SetRoomAlias(ctx context.Context, alias string, roomID string) error { + return nil +} + +func (db MockRoomserverAliasAPIDatabase) GetAliasesForRoomID(ctx context.Context, roomID string) ([]string, error) { + aliases := make([]string, 0) + return aliases, nil +} + +func (db MockRoomserverAliasAPIDatabase) RemoveRoomAlias(ctx context.Context, alias string) error { + return nil +} + +// This method needs to change depending on test case +func (db *MockRoomserverAliasAPIDatabase) GetRoomIDForAlias( + ctx context.Context, + alias string, +) (string, error) { + switch db.mode { + case "empty": + return "", nil + case "error": + return "", fmt.Errorf("found an error from GetRoomIDForAlias") + case "found": + return "123", nil + case "emptyFound": + switch db.attempts { + case 0: + db.attempts = 1 + return "", nil + case 1: + db.attempts = 0 + return "123", nil + default: + return "", nil + } + default: + return "", fmt.Errorf("unknown option used") + } +} + +type MockAppServiceQueryAPI struct { + mode string +} + +// This method can be noop +func (q MockAppServiceQueryAPI) UserIDExists( + ctx context.Context, + req *appserviceAPI.UserIDExistsRequest, + resp *appserviceAPI.UserIDExistsResponse, +) error { + return nil +} + +func (q MockAppServiceQueryAPI) RoomAliasExists( + ctx context.Context, + req *appserviceAPI.RoomAliasExistsRequest, + resp *appserviceAPI.RoomAliasExistsResponse, +) error { + switch q.mode { + case "error": + return fmt.Errorf("found an error from RoomAliasExists") + case "found": + resp.AliasExists = true + return nil + case "empty": + resp.AliasExists = false + return nil + default: + return fmt.Errorf("Unknown option used") + } +} + +func TestGetRoomIDForAlias(t *testing.T) { + type arguments struct { + ctx context.Context + request *roomserverAPI.GetRoomIDForAliasRequest + response *roomserverAPI.GetRoomIDForAliasResponse + } + args := arguments{ + context.Background(), + &roomserverAPI.GetRoomIDForAliasRequest{}, + &roomserverAPI.GetRoomIDForAliasResponse{}, + } + type testCase struct { + name string + dbMode string + queryMode string + wantError bool + errorMsg string + want string + } + tt := []testCase{ + { + "found local alias", + "found", + "error", + false, + "", + "123", + }, + { + "found appservice alias", + "emptyFound", + "found", + false, + "", + "123", + }, + { + "error returned from DB", + "error", + "", + true, + "GetRoomIDForAlias", + "", + }, + { + "error returned from appserviceAPI", + "empty", + "error", + true, + "RoomAliasExists", + "", + }, + { + "no errors but no alias", + "empty", + "empty", + false, + "", + "", + }, + } + + setup := func(dbMode, queryMode string) *RoomserverAliasAPI { + mockAliasAPIDB := &MockRoomserverAliasAPIDatabase{dbMode, 0} + mockAppServiceQueryAPI := MockAppServiceQueryAPI{queryMode} + + return &RoomserverAliasAPI{ + DB: mockAliasAPIDB, + AppserviceAPI: mockAppServiceQueryAPI, + } + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + aliasAPI := setup(tc.dbMode, tc.queryMode) + + err := aliasAPI.GetRoomIDForAlias(args.ctx, args.request, args.response) + if tc.wantError { + if err == nil { + t.Fatalf("Got no error; wanted error from %s", tc.errorMsg) + } else if !strings.Contains(err.Error(), tc.errorMsg) { + t.Fatalf("Got %s; wanted error from %s", err, tc.errorMsg) + } + } else if err != nil { + t.Fatalf("Got %s; wanted no error", err) + } else if args.response.RoomID != tc.want { + t.Errorf("Got '%s'; wanted '%s'", args.response.RoomID, tc.want) + } + }) + } +} diff --git a/show-expected-fail-tests.sh b/show-expected-fail-tests.sh index 277a2c8b9..f58416b2d 100755 --- a/show-expected-fail-tests.sh +++ b/show-expected-fail-tests.sh @@ -1,13 +1,28 @@ #! /bin/bash results_file=$1 +testfile=$2 + +fail_build=0 + +if [ ! -f "$results_file" ]; then + echo "ERROR: Specified results file ${results_file} doesn't exist." + fail_build=1 +fi + +if [ ! -f "$testfile" ]; then + echo "ERROR: Specified testfile ${testfile} doesn't exist." + fail_build=1 +fi + +[ "$fail_build" = 0 ] || exit 1 + passed_but_expected_fail=$(grep ' # TODO passed but expected fail' ${results_file} | sed -E 's/^ok [0-9]+ (\(expected fail\) )?//' | sed -E 's/( \([0-9]+ subtests\))? # TODO passed but expected fail$//') tests_to_add="" already_in_testfile="" -fail_build=0 while read -r test_id; do - grep "${test_id}" testfile > /dev/null 2>&1 + grep "${test_id}" "${testfile}" > /dev/null 2>&1 if [ "$?" != "0" ]; then tests_to_add="${tests_to_add}${test_id}\n" fail_build=1