From e5edf2683df58c6447d8ffdcc0a84151fa1ff48b Mon Sep 17 00:00:00 2001 From: Claudio Costa Date: Mon, 27 Jul 2020 10:20:22 +0200 Subject: [PATCH] [MM-25652] Add /integrity endpoint to local mode API (#15033) * Fix direct/group channel false positives * Move public structures to model package * Expose CheckIntegrity as a local API method * Remove extra file Co-authored-by: Mattermod --- api4/system_local.go | 29 +++ cmd/mattermost/commands/integrity.go | 8 +- model/client4.go | 15 ++ model/integrity.go | 58 ++++++ store/sqlstore/integrity.go | 129 +++++++----- store/sqlstore/integrity_test.go | 299 ++++++++++++++++----------- store/sqlstore/supplier.go | 4 +- store/store.go | 20 +- store/storetest/mocks/Store.go | 12 +- store/storetest/store.go | 5 +- 10 files changed, 367 insertions(+), 212 deletions(-) create mode 100644 model/integrity.go diff --git a/api4/system_local.go b/api4/system_local.go index 5db78a21db..aef50fb071 100644 --- a/api4/system_local.go +++ b/api4/system_local.go @@ -3,9 +3,38 @@ package api4 +import ( + "encoding/json" + "net/http" + + "github.com/mattermost/mattermost-server/v5/audit" + "github.com/mattermost/mattermost-server/v5/model" +) + func (api *API) InitSystemLocal() { api.BaseRoutes.ApiRoot.Handle("/logs", api.ApiLocal(getLogs)).Methods("GET") api.BaseRoutes.ApiRoot.Handle("/server_busy", api.ApiLocal(setServerBusy)).Methods("POST") api.BaseRoutes.ApiRoot.Handle("/server_busy", api.ApiLocal(getServerBusyExpires)).Methods("GET") api.BaseRoutes.ApiRoot.Handle("/server_busy", api.ApiLocal(clearServerBusy)).Methods("DELETE") + api.BaseRoutes.ApiRoot.Handle("/integrity", api.ApiLocal(localCheckIntegrity)).Methods("POST") +} + +func localCheckIntegrity(c *Context, w http.ResponseWriter, r *http.Request) { + auditRec := c.MakeAuditRecord("localCheckIntegrity", audit.Fail) + defer c.LogAuditRec(auditRec) + + var results []model.IntegrityCheckResult + resultsChan := c.App.Srv().Store.CheckIntegrity() + for result := range resultsChan { + results = append(results, result) + } + + data, err := json.Marshal(results) + if err != nil { + c.Err = model.NewAppError("Api4.localCheckIntegrity", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + auditRec.Success() + w.Write(data) } diff --git a/cmd/mattermost/commands/integrity.go b/cmd/mattermost/commands/integrity.go index 4bbe542d0f..d48ab52561 100644 --- a/cmd/mattermost/commands/integrity.go +++ b/cmd/mattermost/commands/integrity.go @@ -8,7 +8,7 @@ import ( "os" "strings" - "github.com/mattermost/mattermost-server/v5/store" + "github.com/mattermost/mattermost-server/v5/model" "github.com/spf13/cobra" ) @@ -24,7 +24,7 @@ func init() { RootCmd.AddCommand(IntegrityCmd) } -func printRelationalIntegrityCheckResult(data store.RelationalIntegrityCheckData, verbose bool) { +func printRelationalIntegrityCheckResult(data model.RelationalIntegrityCheckData, verbose bool) { fmt.Printf("Found %d records in relation %s orphans of relation %s\n", len(data.Records), data.ChildName, data.ParentName) if !verbose { @@ -57,9 +57,9 @@ func printRelationalIntegrityCheckResult(data store.RelationalIntegrityCheckData } } -func printIntegrityCheckResult(result store.IntegrityCheckResult, verbose bool) { +func printIntegrityCheckResult(result model.IntegrityCheckResult, verbose bool) { switch data := result.Data.(type) { - case store.RelationalIntegrityCheckData: + case model.RelationalIntegrityCheckData: printRelationalIntegrityCheckResult(data, verbose) } } diff --git a/model/client4.go b/model/client4.go index 3319383bcc..dc0ac2eab1 100644 --- a/model/client4.go +++ b/model/client4.go @@ -5357,3 +5357,18 @@ func (c *Client4) UpdateSidebarCategoryForTeamForUser(userID, teamID, categoryID return cat, BuildResponse(r) } + +// CheckIntegrity performs a database integrity check. +func (c *Client4) CheckIntegrity() ([]IntegrityCheckResult, *Response) { + r, err := c.DoApiPost("/integrity", "") + if err != nil { + return nil, BuildErrorResponse(r, err) + } + defer closeBody(r) + var results []IntegrityCheckResult + if err := json.NewDecoder(r.Body).Decode(&results); err != nil { + appErr := NewAppError("Api4.CheckIntegrity", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, BuildErrorResponse(r, appErr) + } + return results, BuildResponse(r) +} diff --git a/model/integrity.go b/model/integrity.go new file mode 100644 index 0000000000..744ad07c6f --- /dev/null +++ b/model/integrity.go @@ -0,0 +1,58 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package model + +import ( + "encoding/json" + "errors" +) + +type OrphanedRecord struct { + ParentId *string `json:"parent_id"` + ChildId *string `json:"child_id"` +} + +type RelationalIntegrityCheckData struct { + ParentName string `json:"parent_name"` + ChildName string `json:"child_name"` + ParentIdAttr string `json:"parent_id_attr"` + ChildIdAttr string `json:"child_id_attr"` + Records []OrphanedRecord `json:"records"` +} + +type IntegrityCheckResult struct { + Data interface{} `json:"data"` + Err error `json:"err"` +} + +func (r *IntegrityCheckResult) UnmarshalJSON(b []byte) error { + var data map[string]interface{} + if err := json.Unmarshal(b, &data); err != nil { + return err + } + if d, ok := data["data"]; ok && d != nil { + var rdata RelationalIntegrityCheckData + m := d.(map[string]interface{}) + rdata.ParentName = m["parent_name"].(string) + rdata.ChildName = m["child_name"].(string) + rdata.ParentIdAttr = m["parent_id_attr"].(string) + rdata.ChildIdAttr = m["child_id_attr"].(string) + for _, recData := range m["records"].([]interface{}) { + var record OrphanedRecord + m := recData.(map[string]interface{}) + if val := m["parent_id"]; val != nil { + record.ParentId = NewString(val.(string)) + } + if val := m["child_id"]; val != nil { + record.ChildId = NewString(val.(string)) + } + rdata.Records = append(rdata.Records, record) + } + r.Data = rdata + } + if err, ok := data["err"]; ok && err != nil { + r.Err = errors.New(data["err"].(string)) + } + return nil +} diff --git a/store/sqlstore/integrity.go b/store/sqlstore/integrity.go index ea9d02a631..810f46e7d2 100644 --- a/store/sqlstore/integrity.go +++ b/store/sqlstore/integrity.go @@ -5,7 +5,7 @@ package sqlstore import ( "github.com/mattermost/mattermost-server/v5/mlog" - "github.com/mattermost/mattermost-server/v5/store" + "github.com/mattermost/mattermost-server/v5/model" sq "github.com/Masterminds/squirrel" ) @@ -17,10 +17,11 @@ type relationalCheckConfig struct { childIdAttr string canParentIdBeEmpty bool sortRecords bool + filter interface{} } -func getOrphanedRecords(ss *SqlSupplier, cfg relationalCheckConfig) ([]store.OrphanedRecord, error) { - var records []store.OrphanedRecord +func getOrphanedRecords(ss *SqlSupplier, cfg relationalCheckConfig) ([]model.OrphanedRecord, error) { + var records []model.OrphanedRecord sub := ss.getQueryBuilder(). Select("TRUE"). @@ -43,6 +44,10 @@ func getOrphanedRecords(ss *SqlSupplier, cfg relationalCheckConfig) ([]store.Orp main = main.Where(sq.NotEq{"CT." + cfg.parentIdAttr: ""}) } + if cfg.filter != nil { + main = main.Where(cfg.filter) + } + if cfg.sortRecords { main = main.OrderBy("CT." + cfg.parentIdAttr) } @@ -54,9 +59,9 @@ func getOrphanedRecords(ss *SqlSupplier, cfg relationalCheckConfig) ([]store.Orp return records, err } -func checkParentChildIntegrity(ss *SqlSupplier, config relationalCheckConfig) store.IntegrityCheckResult { - var result store.IntegrityCheckResult - var data store.RelationalIntegrityCheckData +func checkParentChildIntegrity(ss *SqlSupplier, config relationalCheckConfig) model.IntegrityCheckResult { + var result model.IntegrityCheckResult + var data model.RelationalIntegrityCheckData config.sortRecords = true data.Records, result.Err = getOrphanedRecords(ss, config) @@ -73,7 +78,7 @@ func checkParentChildIntegrity(ss *SqlSupplier, config relationalCheckConfig) st return result } -func checkChannelsCommandWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkChannelsCommandWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Channels", parentIdAttr: "ChannelId", @@ -82,7 +87,7 @@ func checkChannelsCommandWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheck }) } -func checkChannelsChannelMemberHistoryIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkChannelsChannelMemberHistoryIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Channels", parentIdAttr: "ChannelId", @@ -91,7 +96,7 @@ func checkChannelsChannelMemberHistoryIntegrity(ss *SqlSupplier) store.Integrity }) } -func checkChannelsChannelMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkChannelsChannelMembersIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Channels", parentIdAttr: "ChannelId", @@ -100,7 +105,7 @@ func checkChannelsChannelMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckR }) } -func checkChannelsIncomingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkChannelsIncomingWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Channels", parentIdAttr: "ChannelId", @@ -109,7 +114,7 @@ func checkChannelsIncomingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityChec }) } -func checkChannelsOutgoingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkChannelsOutgoingWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Channels", parentIdAttr: "ChannelId", @@ -118,7 +123,7 @@ func checkChannelsOutgoingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityChec }) } -func checkChannelsPostsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkChannelsPostsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Channels", parentIdAttr: "ChannelId", @@ -127,7 +132,7 @@ func checkChannelsPostsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkCommandsCommandWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkCommandsCommandWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Commands", parentIdAttr: "CommandId", @@ -136,7 +141,7 @@ func checkCommandsCommandWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheck }) } -func checkPostsFileInfoIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkPostsFileInfoIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Posts", parentIdAttr: "PostId", @@ -145,7 +150,7 @@ func checkPostsFileInfoIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkPostsPostsParentIdIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkPostsPostsParentIdIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Posts", parentIdAttr: "ParentId", @@ -155,7 +160,7 @@ func checkPostsPostsParentIdIntegrity(ss *SqlSupplier) store.IntegrityCheckResul }) } -func checkPostsPostsRootIdIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkPostsPostsRootIdIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Posts", parentIdAttr: "RootId", @@ -165,7 +170,7 @@ func checkPostsPostsRootIdIntegrity(ss *SqlSupplier) store.IntegrityCheckResult }) } -func checkPostsReactionsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkPostsReactionsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Posts", parentIdAttr: "PostId", @@ -174,7 +179,7 @@ func checkPostsReactionsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkSchemesChannelsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkSchemesChannelsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Schemes", parentIdAttr: "SchemeId", @@ -184,7 +189,7 @@ func checkSchemesChannelsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkSchemesTeamsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkSchemesTeamsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Schemes", parentIdAttr: "SchemeId", @@ -194,7 +199,7 @@ func checkSchemesTeamsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkSessionsAuditsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkSessionsAuditsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Sessions", parentIdAttr: "SessionId", @@ -204,16 +209,30 @@ func checkSessionsAuditsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkTeamsChannelsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { - return checkParentChildIntegrity(ss, relationalCheckConfig{ +func checkTeamsChannelsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { + res1 := checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Teams", parentIdAttr: "TeamId", childName: "Channels", childIdAttr: "Id", + filter: sq.NotEq{"CT.Type": []string{model.CHANNEL_DIRECT, model.CHANNEL_GROUP}}, }) + res2 := checkParentChildIntegrity(ss, relationalCheckConfig{ + parentName: "Teams", + parentIdAttr: "TeamId", + childName: "Channels", + childIdAttr: "Id", + canParentIdBeEmpty: true, + filter: sq.Eq{"CT.Type": []string{model.CHANNEL_DIRECT, model.CHANNEL_GROUP}}, + }) + data1 := res1.Data.(model.RelationalIntegrityCheckData) + data2 := res2.Data.(model.RelationalIntegrityCheckData) + data1.Records = append(data1.Records, data2.Records...) + res1.Data = data1 + return res1 } -func checkTeamsCommandsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkTeamsCommandsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Teams", parentIdAttr: "TeamId", @@ -222,7 +241,7 @@ func checkTeamsCommandsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkTeamsIncomingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkTeamsIncomingWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Teams", parentIdAttr: "TeamId", @@ -231,7 +250,7 @@ func checkTeamsIncomingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckRe }) } -func checkTeamsOutgoingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkTeamsOutgoingWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Teams", parentIdAttr: "TeamId", @@ -240,7 +259,7 @@ func checkTeamsOutgoingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckRe }) } -func checkTeamsTeamMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkTeamsTeamMembersIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Teams", parentIdAttr: "TeamId", @@ -249,7 +268,7 @@ func checkTeamsTeamMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResult }) } -func checkUsersAuditsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersAuditsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -259,7 +278,7 @@ func checkUsersAuditsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersCommandWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersCommandWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -268,7 +287,7 @@ func checkUsersCommandWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckRes }) } -func checkUsersChannelMemberHistoryIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersChannelMemberHistoryIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -277,7 +296,7 @@ func checkUsersChannelMemberHistoryIntegrity(ss *SqlSupplier) store.IntegrityChe }) } -func checkUsersChannelMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersChannelMembersIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -286,7 +305,7 @@ func checkUsersChannelMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResu }) } -func checkUsersChannelsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersChannelsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "CreatorId", @@ -296,7 +315,7 @@ func checkUsersChannelsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersCommandsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersCommandsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "CreatorId", @@ -305,7 +324,7 @@ func checkUsersCommandsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersCompliancesIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersCompliancesIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -314,7 +333,7 @@ func checkUsersCompliancesIntegrity(ss *SqlSupplier) store.IntegrityCheckResult }) } -func checkUsersEmojiIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersEmojiIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "CreatorId", @@ -323,7 +342,7 @@ func checkUsersEmojiIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersFileInfoIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersFileInfoIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "CreatorId", @@ -332,7 +351,7 @@ func checkUsersFileInfoIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersIncomingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersIncomingWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -341,7 +360,7 @@ func checkUsersIncomingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckRe }) } -func checkUsersOAuthAccessDataIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersOAuthAccessDataIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -350,7 +369,7 @@ func checkUsersOAuthAccessDataIntegrity(ss *SqlSupplier) store.IntegrityCheckRes }) } -func checkUsersOAuthAppsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersOAuthAppsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "CreatorId", @@ -359,7 +378,7 @@ func checkUsersOAuthAppsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersOAuthAuthDataIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersOAuthAuthDataIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -368,7 +387,7 @@ func checkUsersOAuthAuthDataIntegrity(ss *SqlSupplier) store.IntegrityCheckResul }) } -func checkUsersOutgoingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersOutgoingWebhooksIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "CreatorId", @@ -377,7 +396,7 @@ func checkUsersOutgoingWebhooksIntegrity(ss *SqlSupplier) store.IntegrityCheckRe }) } -func checkUsersPostsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersPostsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -386,7 +405,7 @@ func checkUsersPostsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersPreferencesIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersPreferencesIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -395,7 +414,7 @@ func checkUsersPreferencesIntegrity(ss *SqlSupplier) store.IntegrityCheckResult }) } -func checkUsersReactionsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersReactionsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -404,7 +423,7 @@ func checkUsersReactionsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersSessionsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersSessionsIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -413,7 +432,7 @@ func checkUsersSessionsIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersStatusIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersStatusIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -422,7 +441,7 @@ func checkUsersStatusIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { }) } -func checkUsersTeamMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersTeamMembersIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -431,7 +450,7 @@ func checkUsersTeamMembersIntegrity(ss *SqlSupplier) store.IntegrityCheckResult }) } -func checkUsersUserAccessTokensIntegrity(ss *SqlSupplier) store.IntegrityCheckResult { +func checkUsersUserAccessTokensIntegrity(ss *SqlSupplier) model.IntegrityCheckResult { return checkParentChildIntegrity(ss, relationalCheckConfig{ parentName: "Users", parentIdAttr: "UserId", @@ -440,7 +459,7 @@ func checkUsersUserAccessTokensIntegrity(ss *SqlSupplier) store.IntegrityCheckRe }) } -func checkChannelsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkChannelsIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkChannelsCommandWebhooksIntegrity(ss) results <- checkChannelsChannelMemberHistoryIntegrity(ss) results <- checkChannelsChannelMembersIntegrity(ss) @@ -449,27 +468,27 @@ func checkChannelsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheck results <- checkChannelsPostsIntegrity(ss) } -func checkCommandsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkCommandsIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkCommandsCommandWebhooksIntegrity(ss) } -func checkPostsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkPostsIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkPostsFileInfoIntegrity(ss) results <- checkPostsPostsParentIdIntegrity(ss) results <- checkPostsPostsRootIdIntegrity(ss) results <- checkPostsReactionsIntegrity(ss) } -func checkSchemesIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkSchemesIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkSchemesChannelsIntegrity(ss) results <- checkSchemesTeamsIntegrity(ss) } -func checkSessionsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkSessionsIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkSessionsAuditsIntegrity(ss) } -func checkTeamsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkTeamsIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkTeamsChannelsIntegrity(ss) results <- checkTeamsCommandsIntegrity(ss) results <- checkTeamsIncomingWebhooksIntegrity(ss) @@ -477,7 +496,7 @@ func checkTeamsIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckRes results <- checkTeamsTeamMembersIntegrity(ss) } -func checkUsersIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func checkUsersIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { results <- checkUsersAuditsIntegrity(ss) results <- checkUsersCommandWebhooksIntegrity(ss) results <- checkUsersChannelMemberHistoryIntegrity(ss) @@ -501,7 +520,7 @@ func checkUsersIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckRes results <- checkUsersUserAccessTokensIntegrity(ss) } -func CheckRelationalIntegrity(ss *SqlSupplier, results chan<- store.IntegrityCheckResult) { +func CheckRelationalIntegrity(ss *SqlSupplier, results chan<- model.IntegrityCheckResult) { mlog.Info("Starting relational integrity checks...") checkChannelsIntegrity(ss, results) checkCommandsIntegrity(ss, results) diff --git a/store/sqlstore/integrity_test.go b/store/sqlstore/integrity_test.go index e969df89a8..0ec046b765 100644 --- a/store/sqlstore/integrity_test.go +++ b/store/sqlstore/integrity_test.go @@ -329,7 +329,7 @@ func createTeamWithSchemeId(ss store.Store, schemeId *string) *model.Team { func createUser(ss store.Store) *model.User { m := model.User{} m.Username = model.NewId() - m.Email = "test@example.com" + m.Email = m.Username + "@example.com" user, _ := ss.User().Save(&m) return user } @@ -349,10 +349,10 @@ func TestCheckIntegrity(t *testing.T) { results := ss.CheckIntegrity() require.NotNil(t, results) for result := range results { - require.IsType(t, store.IntegrityCheckResult{}, result) + require.IsType(t, model.IntegrityCheckResult{}, result) require.Nil(t, result.Err) switch data := result.Data.(type) { - case store.RelationalIntegrityCheckData: + case model.RelationalIntegrityCheckData: require.Empty(t, data.Records) } } @@ -385,7 +385,7 @@ func TestCheckChannelsCommandWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkChannelsCommandWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -394,9 +394,9 @@ func TestCheckChannelsCommandWebhooksIntegrity(t *testing.T) { cwh := createCommandWebhook(ss, model.NewId(), model.NewId(), channelId) result := checkChannelsCommandWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &channelId, ChildId: &cwh.Id, }, data.Records[0]) @@ -413,7 +413,7 @@ func TestCheckChannelsChannelMemberHistoryIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkChannelsChannelMemberHistoryIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -424,9 +424,9 @@ func TestCheckChannelsChannelMemberHistoryIntegrity(t *testing.T) { dbmap.Delete(channel) result := checkChannelsChannelMemberHistoryIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &cmh.ChannelId, }, data.Records[0]) dbmap.Delete(user) @@ -443,7 +443,7 @@ func TestCheckChannelsChannelMembersIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkChannelsChannelMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -453,9 +453,9 @@ func TestCheckChannelsChannelMembersIntegrity(t *testing.T) { dbmap.Delete(channel) result := checkChannelsChannelMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &member.ChannelId, }, data.Records[0]) ss.Channel().PermanentDeleteMembersByChannel(member.ChannelId) @@ -471,7 +471,7 @@ func TestCheckChannelsIncomingWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkChannelsIncomingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -480,9 +480,9 @@ func TestCheckChannelsIncomingWebhooksIntegrity(t *testing.T) { wh := createIncomingWebhook(ss, model.NewId(), channelId, model.NewId()) result := checkChannelsIncomingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &channelId, ChildId: &wh.Id, }, data.Records[0]) @@ -499,7 +499,7 @@ func TestCheckChannelsOutgoingWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkChannelsOutgoingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -510,9 +510,9 @@ func TestCheckChannelsOutgoingWebhooksIntegrity(t *testing.T) { dbmap.Delete(channel) result := checkChannelsOutgoingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &channelId, ChildId: &wh.Id, }, data.Records[0]) @@ -529,7 +529,7 @@ func TestCheckChannelsPostsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkChannelsPostsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -537,9 +537,9 @@ func TestCheckChannelsPostsIntegrity(t *testing.T) { post := createPostWithChannelId(ss, model.NewId()) result := checkChannelsPostsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &post.ChannelId, ChildId: &post.Id, }, data.Records[0]) @@ -556,7 +556,7 @@ func TestCheckCommandsCommandWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkCommandsCommandWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -565,9 +565,9 @@ func TestCheckCommandsCommandWebhooksIntegrity(t *testing.T) { cwh := createCommandWebhook(ss, commandId, model.NewId(), model.NewId()) result := checkCommandsCommandWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &commandId, ChildId: &cwh.Id, }, data.Records[0]) @@ -584,7 +584,7 @@ func TestCheckPostsFileInfoIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkPostsFileInfoIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -593,9 +593,9 @@ func TestCheckPostsFileInfoIntegrity(t *testing.T) { info := createFileInfo(ss, postId, model.NewId()) result := checkPostsFileInfoIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &postId, ChildId: &info.Id, }, data.Records[0]) @@ -612,7 +612,7 @@ func TestCheckPostsPostsParentIdIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkPostsPostsParentIdIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -622,7 +622,7 @@ func TestCheckPostsPostsParentIdIntegrity(t *testing.T) { post := createPost(ss, model.NewId(), model.NewId(), root.Id, parent.Id) result := checkPostsPostsParentIdIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) dbmap.Delete(parent) dbmap.Delete(root) @@ -637,9 +637,9 @@ func TestCheckPostsPostsParentIdIntegrity(t *testing.T) { dbmap.Delete(parent) result := checkPostsPostsParentIdIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &parentId, ChildId: &post.Id, }, data.Records[0]) @@ -657,7 +657,7 @@ func TestCheckPostsPostsRootIdIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkPostsPostsRootIdIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -668,9 +668,9 @@ func TestCheckPostsPostsRootIdIntegrity(t *testing.T) { dbmap.Delete(root) result := checkPostsPostsRootIdIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &rootId, ChildId: &post.Id, }, data.Records[0]) @@ -687,7 +687,7 @@ func TestCheckPostsReactionsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkPostsReactionsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -696,9 +696,9 @@ func TestCheckPostsReactionsIntegrity(t *testing.T) { reaction := createReaction(ss, model.NewId(), postId) result := checkPostsReactionsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &postId, }, data.Records[0]) dbmap.Delete(reaction) @@ -714,7 +714,7 @@ func TestCheckSchemesChannelsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkSchemesChannelsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -726,9 +726,9 @@ func TestCheckSchemesChannelsIntegrity(t *testing.T) { dbmap.Delete(scheme) result := checkSchemesChannelsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &schemeId, ChildId: &channel.Id, }, data.Records[0]) @@ -745,7 +745,7 @@ func TestCheckSchemesTeamsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkSchemesTeamsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -757,9 +757,9 @@ func TestCheckSchemesTeamsIntegrity(t *testing.T) { dbmap.Delete(scheme) result := checkSchemesTeamsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &schemeId, ChildId: &team.Id, }, data.Records[0]) @@ -776,7 +776,7 @@ func TestCheckSessionsAuditsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkSessionsAuditsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -788,9 +788,9 @@ func TestCheckSessionsAuditsIntegrity(t *testing.T) { dbmap.Delete(session) result := checkSessionsAuditsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &sessionId, ChildId: &audit.Id, }, data.Records[0]) @@ -807,7 +807,7 @@ func TestCheckTeamsChannelsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkTeamsChannelsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -815,14 +815,63 @@ func TestCheckTeamsChannelsIntegrity(t *testing.T) { channel := createChannelWithTeamId(ss, model.NewId()) result := checkTeamsChannelsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &channel.TeamId, ChildId: &channel.Id, }, data.Records[0]) dbmap.Delete(channel) }) + + t.Run("should not include direct channel with empty teamid", func(t *testing.T) { + channel := createChannelWithTeamId(ss, model.NewId()) + userA := createUser(ss) + userB := createUser(ss) + direct, err := ss.Channel().CreateDirectChannel(userA, userB) + require.NoError(t, err) + require.NotNil(t, direct) + result := checkTeamsChannelsIntegrity(supplier) + require.Nil(t, result.Err) + data := result.Data.(model.RelationalIntegrityCheckData) + require.Len(t, data.Records, 1) + require.Equal(t, model.OrphanedRecord{ + ParentId: &channel.TeamId, + ChildId: &channel.Id, + }, data.Records[0]) + dbmap.Delete(channel) + dbmap.Delete(userA) + dbmap.Delete(userB) + dbmap.Delete(direct) + }) + + t.Run("should include direct channel with non empty teamid", func(t *testing.T) { + channel := createChannelWithTeamId(ss, model.NewId()) + userA := createUser(ss) + userB := createUser(ss) + direct, err := ss.Channel().CreateDirectChannel(userA, userB) + require.NoError(t, err) + require.NotNil(t, direct) + _, err = dbmap.Exec(`UPDATE Channels SET TeamId = 'test' WHERE Id = '` + direct.Id + `'`) + require.NoError(t, err) + result := checkTeamsChannelsIntegrity(supplier) + require.Nil(t, result.Err) + data := result.Data.(model.RelationalIntegrityCheckData) + require.Len(t, data.Records, 2) + require.Equal(t, model.OrphanedRecord{ + ParentId: &channel.TeamId, + ChildId: &channel.Id, + }, data.Records[0]) + require.Equal(t, model.OrphanedRecord{ + ParentId: model.NewString("test"), + ChildId: &direct.Id, + }, data.Records[1]) + dbmap.Delete(channel) + dbmap.Delete(userA) + dbmap.Delete(userB) + dbmap.Delete(direct) + dbmap.Exec("DELETE FROM ChannelMembers") + }) }) } @@ -834,7 +883,7 @@ func TestCheckTeamsCommandsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkTeamsCommandsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -843,9 +892,9 @@ func TestCheckTeamsCommandsIntegrity(t *testing.T) { cmd := createCommand(ss, model.NewId(), teamId) result := checkTeamsCommandsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &teamId, ChildId: &cmd.Id, }, data.Records[0]) @@ -862,7 +911,7 @@ func TestCheckTeamsIncomingWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkTeamsIncomingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -871,9 +920,9 @@ func TestCheckTeamsIncomingWebhooksIntegrity(t *testing.T) { wh := createIncomingWebhook(ss, model.NewId(), model.NewId(), teamId) result := checkTeamsIncomingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &teamId, ChildId: &wh.Id, }, data.Records[0]) @@ -890,7 +939,7 @@ func TestCheckTeamsOutgoingWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkTeamsOutgoingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -899,9 +948,9 @@ func TestCheckTeamsOutgoingWebhooksIntegrity(t *testing.T) { wh := createOutgoingWebhook(ss, model.NewId(), model.NewId(), teamId) result := checkTeamsOutgoingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &teamId, ChildId: &wh.Id, }, data.Records[0]) @@ -918,7 +967,7 @@ func TestCheckTeamsTeamMembersIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkTeamsTeamMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -928,9 +977,9 @@ func TestCheckTeamsTeamMembersIntegrity(t *testing.T) { dbmap.Delete(team) result := checkTeamsTeamMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &team.Id, }, data.Records[0]) ss.Team().RemoveAllMembersByTeam(member.TeamId) @@ -946,7 +995,7 @@ func TestCheckUsersAuditsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersAuditsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -957,9 +1006,9 @@ func TestCheckUsersAuditsIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersAuditsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &audit.Id, }, data.Records[0]) @@ -976,7 +1025,7 @@ func TestCheckUsersCommandWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersCommandWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -985,9 +1034,9 @@ func TestCheckUsersCommandWebhooksIntegrity(t *testing.T) { cwh := createCommandWebhook(ss, model.NewId(), userId, model.NewId()) result := checkUsersCommandWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &cwh.Id, }, data.Records[0]) @@ -1004,7 +1053,7 @@ func TestCheckUsersChannelsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersChannelsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1012,9 +1061,9 @@ func TestCheckUsersChannelsIntegrity(t *testing.T) { channel := createChannelWithCreatorId(ss, model.NewId()) result := checkUsersChannelsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &channel.CreatorId, ChildId: &channel.Id, }, data.Records[0]) @@ -1031,7 +1080,7 @@ func TestCheckUsersChannelMemberHistoryIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersChannelMemberHistoryIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1042,9 +1091,9 @@ func TestCheckUsersChannelMemberHistoryIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersChannelMemberHistoryIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &cmh.UserId, }, data.Records[0]) dbmap.Delete(channel) @@ -1061,7 +1110,7 @@ func TestCheckUsersChannelMembersIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersChannelMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1072,9 +1121,9 @@ func TestCheckUsersChannelMembersIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersChannelMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &member.UserId, }, data.Records[0]) dbmap.Delete(channel) @@ -1091,7 +1140,7 @@ func TestCheckUsersCommandsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersCommandsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1100,9 +1149,9 @@ func TestCheckUsersCommandsIntegrity(t *testing.T) { cmd := createCommand(ss, userId, model.NewId()) result := checkUsersCommandsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &cmd.Id, }, data.Records[0]) @@ -1119,7 +1168,7 @@ func TestCheckUsersCompliancesIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersCompliancesIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1130,9 +1179,9 @@ func TestCheckUsersCompliancesIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersCompliancesIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &compliance.Id, }, data.Records[0]) @@ -1149,7 +1198,7 @@ func TestCheckUsersEmojiIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersEmojiIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1160,9 +1209,9 @@ func TestCheckUsersEmojiIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersEmojiIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &emoji.Id, }, data.Records[0]) @@ -1179,7 +1228,7 @@ func TestCheckUsersFileInfoIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersFileInfoIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1190,9 +1239,9 @@ func TestCheckUsersFileInfoIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersFileInfoIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &info.Id, }, data.Records[0]) @@ -1209,7 +1258,7 @@ func TestCheckUsersIncomingWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersIncomingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1218,9 +1267,9 @@ func TestCheckUsersIncomingWebhooksIntegrity(t *testing.T) { wh := createIncomingWebhook(ss, userId, model.NewId(), model.NewId()) result := checkUsersIncomingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &wh.Id, }, data.Records[0]) @@ -1237,7 +1286,7 @@ func TestCheckUsersOAuthAccessDataIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersOAuthAccessDataIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1248,9 +1297,9 @@ func TestCheckUsersOAuthAccessDataIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersOAuthAccessDataIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &ad.Token, }, data.Records[0]) @@ -1267,7 +1316,7 @@ func TestCheckUsersOAuthAppsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersOAuthAppsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1278,9 +1327,9 @@ func TestCheckUsersOAuthAppsIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersOAuthAppsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &app.Id, }, data.Records[0]) @@ -1297,7 +1346,7 @@ func TestCheckUsersOAuthAuthDataIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersOAuthAuthDataIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1308,9 +1357,9 @@ func TestCheckUsersOAuthAuthDataIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersOAuthAuthDataIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &ad.Code, }, data.Records[0]) @@ -1327,7 +1376,7 @@ func TestCheckUsersOutgoingWebhooksIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersOutgoingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1336,9 +1385,9 @@ func TestCheckUsersOutgoingWebhooksIntegrity(t *testing.T) { wh := createOutgoingWebhook(ss, userId, model.NewId(), model.NewId()) result := checkUsersOutgoingWebhooksIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &wh.Id, }, data.Records[0]) @@ -1355,7 +1404,7 @@ func TestCheckUsersPostsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersPostsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1363,9 +1412,9 @@ func TestCheckUsersPostsIntegrity(t *testing.T) { post := createPostWithUserId(ss, model.NewId()) result := checkUsersPostsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &post.UserId, ChildId: &post.Id, }, data.Records[0]) @@ -1382,7 +1431,7 @@ func TestCheckUsersPreferencesIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersPreferencesIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1394,7 +1443,7 @@ func TestCheckUsersPreferencesIntegrity(t *testing.T) { require.NotNil(t, preferences) result := checkUsersPreferencesIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) dbmap.Exec(`DELETE FROM Preferences`) dbmap.Delete(user) @@ -1409,9 +1458,9 @@ func TestCheckUsersPreferencesIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersPreferencesIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, }, data.Records[0]) dbmap.Exec(`DELETE FROM Preferences`) @@ -1428,7 +1477,7 @@ func TestCheckUsersReactionsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersReactionsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1439,9 +1488,9 @@ func TestCheckUsersReactionsIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersReactionsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, }, data.Records[0]) dbmap.Delete(reaction) @@ -1457,7 +1506,7 @@ func TestCheckUsersSessionsIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersSessionsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1466,9 +1515,9 @@ func TestCheckUsersSessionsIntegrity(t *testing.T) { session := createSession(ss, userId) result := checkUsersSessionsIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &session.Id, }, data.Records[0]) @@ -1485,7 +1534,7 @@ func TestCheckUsersStatusIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersStatusIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1496,9 +1545,9 @@ func TestCheckUsersStatusIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersStatusIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, }, data.Records[0]) dbmap.Delete(status) @@ -1514,7 +1563,7 @@ func TestCheckUsersTeamMembersIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersTeamMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1525,9 +1574,9 @@ func TestCheckUsersTeamMembersIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersTeamMembersIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &member.UserId, }, data.Records[0]) ss.Team().RemoveAllMembersByTeam(member.TeamId) @@ -1544,7 +1593,7 @@ func TestCheckUsersUserAccessTokensIntegrity(t *testing.T) { t.Run("should generate a report with no records", func(t *testing.T) { result := checkUsersUserAccessTokensIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Empty(t, data.Records) }) @@ -1555,9 +1604,9 @@ func TestCheckUsersUserAccessTokensIntegrity(t *testing.T) { dbmap.Delete(user) result := checkUsersUserAccessTokensIntegrity(supplier) require.Nil(t, result.Err) - data := result.Data.(store.RelationalIntegrityCheckData) + data := result.Data.(model.RelationalIntegrityCheckData) require.Len(t, data.Records, 1) - require.Equal(t, store.OrphanedRecord{ + require.Equal(t, model.OrphanedRecord{ ParentId: &userId, ChildId: &uat.Id, }, data.Records[0]) diff --git a/store/sqlstore/supplier.go b/store/sqlstore/supplier.go index 58f9ce98d9..a61204a697 100644 --- a/store/sqlstore/supplier.go +++ b/store/sqlstore/supplier.go @@ -1184,8 +1184,8 @@ func (ss *SqlSupplier) getQueryBuilder() sq.StatementBuilderType { return builder } -func (ss *SqlSupplier) CheckIntegrity() <-chan store.IntegrityCheckResult { - results := make(chan store.IntegrityCheckResult) +func (ss *SqlSupplier) CheckIntegrity() <-chan model.IntegrityCheckResult { + results := make(chan model.IntegrityCheckResult) go CheckRelationalIntegrity(ss, results) return results } diff --git a/store/store.go b/store/store.go index 2c9501c51d..6b3a329ca4 100644 --- a/store/store.go +++ b/store/store.go @@ -67,7 +67,7 @@ type Store interface { TotalMasterDbConnections() int TotalReadDbConnections() int TotalSearchDbConnections() int - CheckIntegrity() <-chan IntegrityCheckResult + CheckIntegrity() <-chan model.IntegrityCheckResult SetContext(context context.Context) Context() context.Context } @@ -776,24 +776,6 @@ type UserGetByIdsOpts struct { Since int64 } -type OrphanedRecord struct { - ParentId *string - ChildId *string -} - -type RelationalIntegrityCheckData struct { - ParentName string - ChildName string - ParentIdAttr string - ChildIdAttr string - Records []OrphanedRecord -} - -type IntegrityCheckResult struct { - Data interface{} - Err error -} - const mySQLDeadlockCode = uint16(1213) // WithDeadlockRetry retries a given f if it throws a deadlock error. diff --git a/store/storetest/mocks/Store.go b/store/storetest/mocks/Store.go index 65c3b2db0c..1e9d5f003f 100644 --- a/store/storetest/mocks/Store.go +++ b/store/storetest/mocks/Store.go @@ -7,9 +7,11 @@ package mocks import ( context "context" - store "github.com/mattermost/mattermost-server/v5/store" + model "github.com/mattermost/mattermost-server/v5/model" mock "github.com/stretchr/testify/mock" + store "github.com/mattermost/mattermost-server/v5/store" + time "time" ) @@ -83,15 +85,15 @@ func (_m *Store) ChannelMemberHistory() store.ChannelMemberHistoryStore { } // CheckIntegrity provides a mock function with given fields: -func (_m *Store) CheckIntegrity() <-chan store.IntegrityCheckResult { +func (_m *Store) CheckIntegrity() <-chan model.IntegrityCheckResult { ret := _m.Called() - var r0 <-chan store.IntegrityCheckResult - if rf, ok := ret.Get(0).(func() <-chan store.IntegrityCheckResult); ok { + var r0 <-chan model.IntegrityCheckResult + if rf, ok := ret.Get(0).(func() <-chan model.IntegrityCheckResult); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan store.IntegrityCheckResult) + r0 = ret.Get(0).(<-chan model.IntegrityCheckResult) } } diff --git a/store/storetest/store.go b/store/storetest/store.go index 3a815400f1..cf7cca7cc7 100644 --- a/store/storetest/store.go +++ b/store/storetest/store.go @@ -7,6 +7,7 @@ import ( "context" "time" + "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/store" "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/stretchr/testify/mock" @@ -94,8 +95,8 @@ func (s *Store) TotalMasterDbConnections() int { return 1 } func (s *Store) TotalReadDbConnections() int { return 1 } func (s *Store) TotalSearchDbConnections() int { return 1 } func (s *Store) GetCurrentSchemaVersion() string { return "" } -func (s *Store) CheckIntegrity() <-chan store.IntegrityCheckResult { - return make(chan store.IntegrityCheckResult) +func (s *Store) CheckIntegrity() <-chan model.IntegrityCheckResult { + return make(chan model.IntegrityCheckResult) } func (s *Store) AssertExpectations(t mock.TestingT) bool {