mirror of
https://github.com/hanzoai/team.git
synced 2026-10-30 14:49:35 +00:00
* [MM-69590] Remove NotificationMonitoring feature flag The NotificationMonitoring feature flag shipped and defaulted true in v9.9. Remove the flag and all conditional gating so notification delivery metrics collection is permanently enabled, gated only by the MetricsSettings.EnableNotificationMetrics admin setting. Co-authored-by: mattermost-code <[email protected]> * [MM-69590] Cover notification metrics client config Assert EnableNotificationMetrics client config prop tracks the MetricsSettings.EnableNotificationMetrics admin setting now that the NotificationMonitoring feature flag gate is removed. Co-authored-by: mattermost-code <[email protected]> * [MM-69590] Cover notification counter gating Add app-layer coverage asserting CountNotification increments the notification counter only when MetricsSettings.EnableNotificationMetrics is set, exercising the un-gated notificationMetricsDisabled path. Co-authored-by: mattermost-code <[email protected]> * [MM-69590] Cover websocket notification counter gating Assert the websocket notification counter increments via the posted-ack broadcast hook only when MetricsSettings.EnableNotificationMetrics is set, exercising the un-gated incrementWebsocketCounter path. Co-authored-by: mattermost-code <[email protected]> * Address PR feedback: 0 answered, 1 resolved, 0 declined Document that MetricsSettings.EnableNotificationMetrics must be set to true for notification monitoring, matching the code gating and the push-notification-health-targets doc. --------- Co-authored-by: mattermost-code <[email protected]> Co-authored-by: Hanzo Dev <[email protected]>
210 lines
6.3 KiB
Go
210 lines
6.3 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
"github.com/mattermost/mattermost/server/v8/channels/app/platform"
|
|
"github.com/mattermost/mattermost/server/v8/enterprise/metrics"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
prometheusModels "github.com/prometheus/client_model/go"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func configureMetrics(th *TestHelper) {
|
|
th.App.Srv().SetLicense(nil) // clear license
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.MetricsSettings.Enable = true
|
|
*cfg.MetricsSettings.ListenAddress = ":0"
|
|
})
|
|
th.App.Srv().SetLicense(model.NewTestLicense("metrics"))
|
|
}
|
|
|
|
func TestMobileMetrics(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := SetupEnterprise(t, StartMetrics)
|
|
|
|
configureMetrics(th)
|
|
mi := th.App.Metrics()
|
|
|
|
miImpl, ok := mi.(*metrics.MetricsInterfaceImpl)
|
|
require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi))
|
|
m := &prometheusModels.Metric{}
|
|
|
|
for _, platform := range []string{"ios", "android"} {
|
|
ttcc := []struct {
|
|
name string
|
|
histogramVec *prometheus.HistogramVec
|
|
elapsed float64
|
|
metricName model.MetricType
|
|
}{
|
|
{
|
|
name: "load duration",
|
|
histogramVec: miImpl.MobileClientLoadDuration,
|
|
elapsed: 5001,
|
|
metricName: model.MobileClientLoadDuration,
|
|
},
|
|
{
|
|
name: "channel switch duration",
|
|
histogramVec: miImpl.MobileClientChannelSwitchDuration,
|
|
elapsed: 501,
|
|
metricName: model.MobileClientChannelSwitchDuration,
|
|
},
|
|
{
|
|
name: "team switch duration",
|
|
histogramVec: miImpl.MobileClientTeamSwitchDuration,
|
|
elapsed: 301,
|
|
metricName: model.MobileClientTeamSwitchDuration,
|
|
},
|
|
}
|
|
|
|
histograms := []*model.MetricSample{}
|
|
var start float64 = 125
|
|
end := start + float64(len(ttcc))
|
|
// Precheck
|
|
for _, tc := range ttcc {
|
|
actualMetric, err := tc.histogramVec.GetMetricWith(prometheus.Labels{"platform": platform})
|
|
require.NoError(t, err)
|
|
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
|
require.Equal(t, uint64(0), m.Histogram.GetSampleCount())
|
|
require.Equal(t, 0.0, m.Histogram.GetSampleSum())
|
|
histograms = append(histograms, &model.MetricSample{
|
|
Metric: tc.metricName,
|
|
Value: tc.elapsed,
|
|
})
|
|
}
|
|
|
|
appErr := th.App.RegisterPerformanceReport(th.Context, &model.PerformanceReport{
|
|
Version: "0.1.0",
|
|
ClientID: "",
|
|
Labels: map[string]string{
|
|
"platform": platform,
|
|
},
|
|
Start: start,
|
|
End: end,
|
|
Counters: []*model.MetricSample{},
|
|
Histograms: histograms,
|
|
})
|
|
require.Nil(t, appErr)
|
|
|
|
// After check
|
|
for _, tc := range ttcc {
|
|
actualMetric, err := tc.histogramVec.GetMetricWith(prometheus.Labels{"platform": platform})
|
|
require.NoError(t, err)
|
|
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
|
require.Equal(t, uint64(1), m.Histogram.GetSampleCount())
|
|
require.InDelta(t, tc.elapsed/1000, m.Histogram.GetSampleSum(), 0.001, "not equal value in %s", tc.name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCountNotificationMetrics(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := SetupEnterprise(t, StartMetrics)
|
|
|
|
configureMetrics(th)
|
|
mi := th.App.Metrics()
|
|
|
|
miImpl, ok := mi.(*metrics.MetricsInterfaceImpl)
|
|
require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi))
|
|
|
|
counterValue := func() float64 {
|
|
counter, err := miImpl.NotificationTotalCounters.GetMetricWith(prometheus.Labels{
|
|
"type": string(model.NotificationTypePush),
|
|
"platform": "ios",
|
|
})
|
|
require.NoError(t, err)
|
|
m := &prometheusModels.Metric{}
|
|
require.NoError(t, counter.Write(m))
|
|
return m.Counter.GetValue()
|
|
}
|
|
|
|
t.Run("counts when notification metrics are enabled", func(t *testing.T) {
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.MetricsSettings.EnableNotificationMetrics = true
|
|
})
|
|
|
|
before := counterValue()
|
|
th.App.CountNotification(model.NotificationTypePush, "ios")
|
|
require.Equal(t, before+1, counterValue())
|
|
})
|
|
|
|
t.Run("does not count when notification metrics are disabled", func(t *testing.T) {
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.MetricsSettings.EnableNotificationMetrics = false
|
|
})
|
|
|
|
before := counterValue()
|
|
th.App.CountNotification(model.NotificationTypePush, "ios")
|
|
require.Equal(t, before, counterValue())
|
|
})
|
|
}
|
|
|
|
func TestWebsocketNotificationCounter(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := SetupEnterprise(t, StartMetrics)
|
|
|
|
configureMetrics(th)
|
|
mi := th.App.Metrics()
|
|
|
|
miImpl, ok := mi.(*metrics.MetricsInterfaceImpl)
|
|
require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi))
|
|
|
|
counterValue := func() float64 {
|
|
counter, err := miImpl.NotificationTotalCounters.GetMetricWith(prometheus.Labels{
|
|
"type": string(model.NotificationTypeWebsocket),
|
|
"platform": model.NotificationNoPlatform,
|
|
})
|
|
require.NoError(t, err)
|
|
m := &prometheusModels.Metric{}
|
|
require.NoError(t, counter.Write(m))
|
|
return m.Counter.GetValue()
|
|
}
|
|
|
|
hook := &postedAckBroadcastHook{}
|
|
userID := model.NewId()
|
|
webConn := &platform.WebConn{
|
|
UserId: userID,
|
|
Platform: th.Server.Platform(),
|
|
PostedAck: true,
|
|
}
|
|
webConn.Active.Store(true)
|
|
webConn.SetSession(&model.Session{})
|
|
|
|
// Process an acked broadcast that reaches incrementWebsocketCounter.
|
|
ackPostedBroadcast := func() {
|
|
msg := platform.MakeHookedWebSocketEvent(model.NewWebSocketEvent(model.WebsocketEventPosted, "", "", "", nil, ""))
|
|
err := hook.Process(msg, webConn, map[string]any{
|
|
"posted_user_id": model.NewId(),
|
|
"channel_type": model.ChannelTypeOpen,
|
|
"users": []string{userID},
|
|
})
|
|
require.NoError(t, err)
|
|
require.True(t, msg.Event().GetData()["should_ack"].(bool))
|
|
}
|
|
|
|
t.Run("counts when notification metrics are enabled", func(t *testing.T) {
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.MetricsSettings.EnableNotificationMetrics = true
|
|
})
|
|
|
|
before := counterValue()
|
|
ackPostedBroadcast()
|
|
require.Equal(t, before+1, counterValue())
|
|
})
|
|
|
|
t.Run("does not count when notification metrics are disabled", func(t *testing.T) {
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.MetricsSettings.EnableNotificationMetrics = false
|
|
})
|
|
|
|
before := counterValue()
|
|
ackPostedBroadcast()
|
|
require.Equal(t, before, counterValue())
|
|
})
|
|
}
|