Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MI-3624] Add some additional metrics #354

Merged
merged 13 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 53 additions & 10 deletions server/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"testing"
"time"

"github.com/mattermost/mattermost-plugin-msteams-sync/server/handlers"
metricsmocks "github.com/mattermost/mattermost-plugin-msteams-sync/server/metrics/mocks"
"github.com/mattermost/mattermost-plugin-msteams-sync/server/msteams"
clientmocks "github.com/mattermost/mattermost-plugin-msteams-sync/server/msteams/mocks"
storemocks "github.com/mattermost/mattermost-plugin-msteams-sync/server/store/mocks"
Expand Down Expand Up @@ -47,6 +49,8 @@ func TestSubscriptionValidation(t *testing.T) {

func TestSubscriptionInvalidRequest(t *testing.T) {
plugin := newTestPlugin(t)
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveAPIEndpointDuration", "/changes", http.MethodPost, fmt.Sprint(http.StatusBadRequest), mock.AnythingOfType("float64")).Times(1)
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodPost, "/changes", strings.NewReader(""))
Expand Down Expand Up @@ -86,8 +90,9 @@ func TestSubscriptionNewMesage(t *testing.T) {
},
},
func() {
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveChangeEventTotal", handlers.ActionCreated).Times(1)
},
202,
http.StatusAccepted,
"",
},
{
Expand All @@ -103,9 +108,10 @@ func TestSubscriptionNewMesage(t *testing.T) {
},
},
func() {
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil)
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil).Times(1)
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveChangeEventTotal", handlers.ActionCreated).Times(1)
},
202,
http.StatusAccepted,
"",
},
{
Expand All @@ -121,9 +127,10 @@ func TestSubscriptionNewMesage(t *testing.T) {
},
},
func() {
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil)
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil).Times(1)
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveChangeEventTotal", handlers.ActionCreated).Times(1)
},
202,
http.StatusAccepted,
"",
},
{
Expand All @@ -139,9 +146,10 @@ func TestSubscriptionNewMesage(t *testing.T) {
},
},
func() {
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil)
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil).Times(1)
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveChangeEventTotal", handlers.ActionCreated).Times(1)
},
202,
http.StatusAccepted,
"",
},
{
Expand All @@ -157,10 +165,10 @@ func TestSubscriptionNewMesage(t *testing.T) {
},
},
func() {
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil)
plugin.API.(*plugintest.API).On("LogError", "Unable to process created activity", "activity", mock.Anything, "error", "Invalid webhook secret").Return(nil)
plugin.store.(*storemocks.Store).On("GetTokenForMattermostUser", "bot-user-id").Return(&oauth2.Token{}, nil).Times(1)
plugin.API.(*plugintest.API).On("LogError", "Unable to process created activity", "activity", mock.Anything, "error", "Invalid webhook secret").Return(nil).Times(1)
},
400,
http.StatusBadRequest,
"Invalid webhook secret\n",
},
}
Expand All @@ -170,6 +178,11 @@ func TestSubscriptionNewMesage(t *testing.T) {
require.NoError(t, err)

tc.PopulateMocks()
if tc.ExpectedBody != "" {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)
} else {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementChangeEventQueueLength", handlers.ActionCreated).Times(1)
}

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodPost, "/changes", bytes.NewReader(data))
Expand Down Expand Up @@ -239,6 +252,7 @@ func TestGetAvatarNotFound(t *testing.T) {
plugin.store.(*storemocks.Store).On("GetAvatarCache", "user-id").Return(nil, &model.AppError{Message: "not-found"}).Times(1)
plugin.msteamsAppClient.(*clientmocks.Client).On("GetUserAvatar", "user-id").Return(nil, errors.New("not-found")).Times(1)
plugin.API.(*plugintest.API).On("LogError", "Unable to get user avatar", "msteamsUserID", "user-id", "error", "not-found").Return(nil)
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/avatar/user-id", nil)
Expand Down Expand Up @@ -326,6 +340,15 @@ func TestProcessActivity(t *testing.T) {
t.Run(test.Name, func(t *testing.T) {
assert := assert.New(t)
plugin := newTestPlugin(t)
if test.ExpectedResult != "" {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)
}

if test.ExpectedStatusCode == http.StatusAccepted {
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveChangeEventTotal", "mockChangeType").Times(1)
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementChangeEventQueueLength", "mockChangeType").Times(1)
}

test.SetupStore(plugin.store.(*storemocks.Store))
test.SetupAPI(plugin.API.(*plugintest.API))
test.SetupClient(plugin.msteamsAppClient.(*clientmocks.Client), plugin.clientBuilderWithToken("", "", "", "", nil, nil).(*clientmocks.Client))
Expand Down Expand Up @@ -451,6 +474,14 @@ func TestProcessLifecycle(t *testing.T) {
t.Run(test.Name, func(t *testing.T) {
assert := assert.New(t)
plugin := newTestPlugin(t)
if test.ExpectedResult != "" {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)
}

if test.ExpectedStatusCode == http.StatusOK {
plugin.metricsService.(*metricsmocks.Metrics).On("ObserveLifecycleEventTotal", mock.AnythingOfType("string")).Times(1)
}

test.SetupStore(plugin.store.(*storemocks.Store))
test.SetupAPI(plugin.API.(*plugintest.API))
test.SetupClient(plugin.msteamsAppClient.(*clientmocks.Client), plugin.clientBuilderWithToken("", "", "", "", nil, nil).(*clientmocks.Client))
Expand Down Expand Up @@ -801,6 +832,10 @@ func TestConnect(t *testing.T) {
t.Run(test.Name, func(t *testing.T) {
assert := assert.New(t)
plugin := newTestPlugin(t)
if test.ExpectedResult != "" {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)
}

mockAPI := &plugintest.API{}

plugin.SetAPI(mockAPI)
Expand Down Expand Up @@ -890,6 +925,10 @@ func TestGetConnectedUsers(t *testing.T) {
t.Run(test.Name, func(t *testing.T) {
assert := assert.New(t)
plugin := newTestPlugin(t)
if test.ExpectedResult != "" {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)
}

mockAPI := &plugintest.API{}

plugin.SetAPI(mockAPI)
Expand Down Expand Up @@ -979,6 +1018,10 @@ func TestGetConnectedUsersFile(t *testing.T) {
t.Run(test.Name, func(t *testing.T) {
assert := assert.New(t)
plugin := newTestPlugin(t)
if test.ExpectedResult != "" {
plugin.metricsService.(*metricsmocks.Metrics).On("IncrementHTTPErrors").Times(1)
}

mockAPI := &plugintest.API{}

plugin.SetAPI(mockAPI)
Expand Down
21 changes: 18 additions & 3 deletions server/handlers/attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ func (ah *ActivityHandler) handleAttachments(channelID, userID, text string, msg
attachments := []string{}
newText := text
parentID := ""
countAttachments := 0
countNonFileAttachments := 0
countFileAttachments := 0
var client msteams.Client
if chat == nil {
client = ah.plugin.GetClientForApp()
Expand All @@ -114,19 +115,26 @@ func (ah *ActivityHandler) handleAttachments(channelID, userID, text string, msg
return "", nil, "", errorFound
}

isDirectMessage := false
if chat != nil {
isDirectMessage = true
}

for _, a := range msg.Attachments {
// remove the attachment tags from the text
newText = attachRE.ReplaceAllString(newText, "")

// handle a code snippet (code block)
if a.ContentType == "application/vnd.microsoft.card.codesnippet" {
newText = ah.handleCodeSnippet(client, a, newText)
countNonFileAttachments++
continue
}

// handle a message reference (reply)
if a.ContentType == "messageReference" {
parentID, newText = ah.handleMessageReference(a, msg.ChatID+msg.ChannelID, newText)
countNonFileAttachments++
continue
}

Expand All @@ -143,19 +151,22 @@ func (ah *ActivityHandler) handleAttachments(channelID, userID, text string, msg
attachmentData, err = ah.handleDownloadFile(a.ContentURL, client)
if err != nil {
ah.plugin.GetAPI().LogError("failed to download the file", "filename", a.Name, "error", err.Error())
ah.plugin.GetMetrics().ObserveFileCount(ActionCreated, actionSourceMSTeams, discardedReasonUnableToGetTeamsData, isDirectMessage)
continue
}
} else {
fileSize, downloadURL, err = client.GetFileSizeAndDownloadURL(a.ContentURL)
if err != nil {
ah.plugin.GetAPI().LogError("failed to get file size and download URL", "error", err.Error())
ah.plugin.GetMetrics().ObserveFileCount(ActionCreated, actionSourceMSTeams, discardedReasonUnableToGetTeamsData, isDirectMessage)
continue
}

fileSizeAllowed := *ah.plugin.GetAPI().GetConfig().FileSettings.MaxFileSize
if fileSize > fileSizeAllowed {
ah.plugin.GetAPI().LogError("skipping file download from MS Teams because the file size is greater than the allowed size")
errorFound = true
ah.plugin.GetMetrics().ObserveFileCount(ActionCreated, actionSourceMSTeams, discardedReasonMaxFileSizeExceeded, isDirectMessage)
continue
}

Expand All @@ -164,6 +175,7 @@ func (ah *ActivityHandler) handleAttachments(channelID, userID, text string, msg
attachmentData, err = client.GetFileContent(downloadURL)
if err != nil {
ah.plugin.GetAPI().LogError("failed to get file content", "error", err.Error())
ah.plugin.GetMetrics().ObserveFileCount(ActionCreated, actionSourceMSTeams, discardedReasonUnableToGetTeamsData, isDirectMessage)
continue
}
}
Expand All @@ -184,12 +196,15 @@ func (ah *ActivityHandler) handleAttachments(channelID, userID, text string, msg
}

if fileInfoID == "" {
ah.plugin.GetMetrics().ObserveFileCount(ActionCreated, actionSourceMSTeams, discardedReasonEmptyFileID, isDirectMessage)
continue
}
attachments = append(attachments, fileInfoID)
countAttachments++
if countAttachments == 10 {
ah.plugin.GetMetrics().ObserveFileCount(ActionCreated, actionSourceMSTeams, "", isDirectMessage)
countFileAttachments++
if countFileAttachments == maxFileAttachmentsSupported {
ah.plugin.GetAPI().LogDebug("discarding the rest of the attachments as Mattermost supports only 10 attachments per post")
ah.plugin.GetMetrics().ObserveFilesCount(ActionCreated, actionSourceMSTeams, discardedReasonFileLimitReached, isDirectMessage, int64(len(msg.Attachments)-countNonFileAttachments-countFileAttachments))
break
}
}
Expand Down
Loading
Loading