From 658e82f8bcfc78d8489f9687e88fb712af0ea75f Mon Sep 17 00:00:00 2001 From: Till <2353100+S7evinK@users.noreply.github.com> Date: Thu, 5 May 2022 12:00:18 +0200 Subject: [PATCH] Don't use in-memory db for userapi tests (#2417) * Don't use in-memory db * Use WithAllDatabases where possible --- userapi/userapi_test.go | 205 +++++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 96 deletions(-) diff --git a/userapi/userapi_test.go b/userapi/userapi_test.go index 64e23909a..e614765a2 100644 --- a/userapi/userapi_test.go +++ b/userapi/userapi_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package userapi +package userapi_test import ( "context" @@ -23,15 +23,17 @@ import ( "time" "github.com/gorilla/mux" + "github.com/matrix-org/dendrite/internal/httputil" + internalTest "github.com/matrix-org/dendrite/internal/test" + "github.com/matrix-org/dendrite/test" + "github.com/matrix-org/dendrite/userapi" + "github.com/matrix-org/dendrite/userapi/inthttp" "github.com/matrix-org/gomatrixserverlib" "golang.org/x/crypto/bcrypt" - "github.com/matrix-org/dendrite/internal/httputil" - "github.com/matrix-org/dendrite/internal/test" "github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/dendrite/userapi/internal" - "github.com/matrix-org/dendrite/userapi/inthttp" "github.com/matrix-org/dendrite/userapi/storage" ) @@ -43,16 +45,15 @@ type apiTestOpts struct { loginTokenLifetime time.Duration } -func MustMakeInternalAPI(t *testing.T, opts apiTestOpts) (api.UserInternalAPI, storage.Database) { +func MustMakeInternalAPI(t *testing.T, opts apiTestOpts, dbType test.DBType) (api.UserInternalAPI, storage.Database, func()) { if opts.loginTokenLifetime == 0 { opts.loginTokenLifetime = api.DefaultLoginTokenLifetime * time.Millisecond } - dbopts := &config.DatabaseOptions{ - ConnectionString: "file::memory:", - MaxOpenConnections: 1, - MaxIdleConnections: 1, - } - accountDB, err := storage.NewUserAPIDatabase(nil, dbopts, serverName, bcrypt.MinCost, config.DefaultOpenIDTokenLifetimeMS, opts.loginTokenLifetime, "") + connStr, close := test.PrepareDBConnectionString(t, dbType) + + accountDB, err := storage.NewUserAPIDatabase(nil, &config.DatabaseOptions{ + ConnectionString: config.DataSource(connStr), + }, serverName, bcrypt.MinCost, config.DefaultOpenIDTokenLifetimeMS, opts.loginTokenLifetime, "") if err != nil { t.Fatalf("failed to create account DB: %s", err) } @@ -66,13 +67,15 @@ func MustMakeInternalAPI(t *testing.T, opts apiTestOpts) (api.UserInternalAPI, s return &internal.UserInternalAPI{ DB: accountDB, ServerName: cfg.Matrix.ServerName, - }, accountDB + }, accountDB, close } func TestQueryProfile(t *testing.T) { aliceAvatarURL := "mxc://example.com/alice" aliceDisplayName := "Alice" - userAPI, accountDB := MustMakeInternalAPI(t, apiTestOpts{}) + // only one DBType, since userapi.AddInternalRoutes complains about multiple prometheus counters added + userAPI, accountDB, close := MustMakeInternalAPI(t, apiTestOpts{}, test.DBTypeSQLite) + defer close() _, err := accountDB.CreateAccount(context.TODO(), "alice", "foobar", "", api.AccountTypeUser) if err != nil { t.Fatalf("failed to make account: %s", err) @@ -131,8 +134,8 @@ func TestQueryProfile(t *testing.T) { t.Run("HTTP API", func(t *testing.T) { router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter() - AddInternalRoutes(router, userAPI) - apiURL, cancel := test.ListenAndServe(t, router, false) + userapi.AddInternalRoutes(router, userAPI) + apiURL, cancel := internalTest.ListenAndServe(t, router, false) defer cancel() httpAPI, err := inthttp.NewUserAPIClient(apiURL, &http.Client{}) if err != nil { @@ -149,110 +152,120 @@ func TestLoginToken(t *testing.T) { ctx := context.Background() t.Run("tokenLoginFlow", func(t *testing.T) { - userAPI, accountDB := MustMakeInternalAPI(t, apiTestOpts{}) + test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) { + userAPI, accountDB, close := MustMakeInternalAPI(t, apiTestOpts{}, dbType) + defer close() + _, err := accountDB.CreateAccount(ctx, "auser", "apassword", "", api.AccountTypeUser) + if err != nil { + t.Fatalf("failed to make account: %s", err) + } - _, err := accountDB.CreateAccount(ctx, "auser", "apassword", "", api.AccountTypeUser) - if err != nil { - t.Fatalf("failed to make account: %s", err) - } + t.Log("Creating a login token like the SSO callback would...") - t.Log("Creating a login token like the SSO callback would...") + creq := api.PerformLoginTokenCreationRequest{ + Data: api.LoginTokenData{UserID: "@auser:example.com"}, + } + var cresp api.PerformLoginTokenCreationResponse + if err := userAPI.PerformLoginTokenCreation(ctx, &creq, &cresp); err != nil { + t.Fatalf("PerformLoginTokenCreation failed: %v", err) + } - creq := api.PerformLoginTokenCreationRequest{ - Data: api.LoginTokenData{UserID: "@auser:example.com"}, - } - var cresp api.PerformLoginTokenCreationResponse - if err := userAPI.PerformLoginTokenCreation(ctx, &creq, &cresp); err != nil { - t.Fatalf("PerformLoginTokenCreation failed: %v", err) - } + if cresp.Metadata.Token == "" { + t.Errorf("PerformLoginTokenCreation Token: got %q, want non-empty", cresp.Metadata.Token) + } + if cresp.Metadata.Expiration.Before(time.Now()) { + t.Errorf("PerformLoginTokenCreation Expiration: got %v, want non-expired", cresp.Metadata.Expiration) + } - if cresp.Metadata.Token == "" { - t.Errorf("PerformLoginTokenCreation Token: got %q, want non-empty", cresp.Metadata.Token) - } - if cresp.Metadata.Expiration.Before(time.Now()) { - t.Errorf("PerformLoginTokenCreation Expiration: got %v, want non-expired", cresp.Metadata.Expiration) - } + t.Log("Querying the login token like /login with m.login.token would...") - t.Log("Querying the login token like /login with m.login.token would...") + qreq := api.QueryLoginTokenRequest{Token: cresp.Metadata.Token} + var qresp api.QueryLoginTokenResponse + if err := userAPI.QueryLoginToken(ctx, &qreq, &qresp); err != nil { + t.Fatalf("QueryLoginToken failed: %v", err) + } - qreq := api.QueryLoginTokenRequest{Token: cresp.Metadata.Token} - var qresp api.QueryLoginTokenResponse - if err := userAPI.QueryLoginToken(ctx, &qreq, &qresp); err != nil { - t.Fatalf("QueryLoginToken failed: %v", err) - } + if qresp.Data == nil { + t.Errorf("QueryLoginToken Data: got %v, want non-nil", qresp.Data) + } else if want := "@auser:example.com"; qresp.Data.UserID != want { + t.Errorf("QueryLoginToken UserID: got %q, want %q", qresp.Data.UserID, want) + } - if qresp.Data == nil { - t.Errorf("QueryLoginToken Data: got %v, want non-nil", qresp.Data) - } else if want := "@auser:example.com"; qresp.Data.UserID != want { - t.Errorf("QueryLoginToken UserID: got %q, want %q", qresp.Data.UserID, want) - } + t.Log("Deleting the login token like /login with m.login.token would...") - t.Log("Deleting the login token like /login with m.login.token would...") - - dreq := api.PerformLoginTokenDeletionRequest{Token: cresp.Metadata.Token} - var dresp api.PerformLoginTokenDeletionResponse - if err := userAPI.PerformLoginTokenDeletion(ctx, &dreq, &dresp); err != nil { - t.Fatalf("PerformLoginTokenDeletion failed: %v", err) - } + dreq := api.PerformLoginTokenDeletionRequest{Token: cresp.Metadata.Token} + var dresp api.PerformLoginTokenDeletionResponse + if err := userAPI.PerformLoginTokenDeletion(ctx, &dreq, &dresp); err != nil { + t.Fatalf("PerformLoginTokenDeletion failed: %v", err) + } + }) }) t.Run("expiredTokenIsNotReturned", func(t *testing.T) { - userAPI, _ := MustMakeInternalAPI(t, apiTestOpts{loginTokenLifetime: -1 * time.Second}) + test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) { + userAPI, _, close := MustMakeInternalAPI(t, apiTestOpts{loginTokenLifetime: -1 * time.Second}, dbType) + defer close() - creq := api.PerformLoginTokenCreationRequest{ - Data: api.LoginTokenData{UserID: "@auser:example.com"}, - } - var cresp api.PerformLoginTokenCreationResponse - if err := userAPI.PerformLoginTokenCreation(ctx, &creq, &cresp); err != nil { - t.Fatalf("PerformLoginTokenCreation failed: %v", err) - } + creq := api.PerformLoginTokenCreationRequest{ + Data: api.LoginTokenData{UserID: "@auser:example.com"}, + } + var cresp api.PerformLoginTokenCreationResponse + if err := userAPI.PerformLoginTokenCreation(ctx, &creq, &cresp); err != nil { + t.Fatalf("PerformLoginTokenCreation failed: %v", err) + } - qreq := api.QueryLoginTokenRequest{Token: cresp.Metadata.Token} - var qresp api.QueryLoginTokenResponse - if err := userAPI.QueryLoginToken(ctx, &qreq, &qresp); err != nil { - t.Fatalf("QueryLoginToken failed: %v", err) - } + qreq := api.QueryLoginTokenRequest{Token: cresp.Metadata.Token} + var qresp api.QueryLoginTokenResponse + if err := userAPI.QueryLoginToken(ctx, &qreq, &qresp); err != nil { + t.Fatalf("QueryLoginToken failed: %v", err) + } - if qresp.Data != nil { - t.Errorf("QueryLoginToken Data: got %v, want nil", qresp.Data) - } + if qresp.Data != nil { + t.Errorf("QueryLoginToken Data: got %v, want nil", qresp.Data) + } + }) }) t.Run("deleteWorks", func(t *testing.T) { - userAPI, _ := MustMakeInternalAPI(t, apiTestOpts{}) + test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) { + userAPI, _, close := MustMakeInternalAPI(t, apiTestOpts{}, dbType) + defer close() - creq := api.PerformLoginTokenCreationRequest{ - Data: api.LoginTokenData{UserID: "@auser:example.com"}, - } - var cresp api.PerformLoginTokenCreationResponse - if err := userAPI.PerformLoginTokenCreation(ctx, &creq, &cresp); err != nil { - t.Fatalf("PerformLoginTokenCreation failed: %v", err) - } + creq := api.PerformLoginTokenCreationRequest{ + Data: api.LoginTokenData{UserID: "@auser:example.com"}, + } + var cresp api.PerformLoginTokenCreationResponse + if err := userAPI.PerformLoginTokenCreation(ctx, &creq, &cresp); err != nil { + t.Fatalf("PerformLoginTokenCreation failed: %v", err) + } - dreq := api.PerformLoginTokenDeletionRequest{Token: cresp.Metadata.Token} - var dresp api.PerformLoginTokenDeletionResponse - if err := userAPI.PerformLoginTokenDeletion(ctx, &dreq, &dresp); err != nil { - t.Fatalf("PerformLoginTokenDeletion failed: %v", err) - } + dreq := api.PerformLoginTokenDeletionRequest{Token: cresp.Metadata.Token} + var dresp api.PerformLoginTokenDeletionResponse + if err := userAPI.PerformLoginTokenDeletion(ctx, &dreq, &dresp); err != nil { + t.Fatalf("PerformLoginTokenDeletion failed: %v", err) + } - qreq := api.QueryLoginTokenRequest{Token: cresp.Metadata.Token} - var qresp api.QueryLoginTokenResponse - if err := userAPI.QueryLoginToken(ctx, &qreq, &qresp); err != nil { - t.Fatalf("QueryLoginToken failed: %v", err) - } + qreq := api.QueryLoginTokenRequest{Token: cresp.Metadata.Token} + var qresp api.QueryLoginTokenResponse + if err := userAPI.QueryLoginToken(ctx, &qreq, &qresp); err != nil { + t.Fatalf("QueryLoginToken failed: %v", err) + } - if qresp.Data != nil { - t.Errorf("QueryLoginToken Data: got %v, want nil", qresp.Data) - } + if qresp.Data != nil { + t.Errorf("QueryLoginToken Data: got %v, want nil", qresp.Data) + } + }) }) t.Run("deleteUnknownIsNoOp", func(t *testing.T) { - userAPI, _ := MustMakeInternalAPI(t, apiTestOpts{}) - - dreq := api.PerformLoginTokenDeletionRequest{Token: "non-existent token"} - var dresp api.PerformLoginTokenDeletionResponse - if err := userAPI.PerformLoginTokenDeletion(ctx, &dreq, &dresp); err != nil { - t.Fatalf("PerformLoginTokenDeletion failed: %v", err) - } + test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) { + userAPI, _, close := MustMakeInternalAPI(t, apiTestOpts{}, dbType) + defer close() + dreq := api.PerformLoginTokenDeletionRequest{Token: "non-existent token"} + var dresp api.PerformLoginTokenDeletionResponse + if err := userAPI.PerformLoginTokenDeletion(ctx, &dreq, &dresp); err != nil { + t.Fatalf("PerformLoginTokenDeletion failed: %v", err) + } + }) }) }