forked from Silverfish/proton-bridge
feat(BRIDGE-150): Observability service modification; user distinction utility & heartbeat; various observbility metrics & relevant integration tests
This commit is contained in:
@ -267,6 +267,8 @@ func newBridge(
|
||||
|
||||
unleashService := unleash.NewBridgeService(ctx, api, locator, panicHandler)
|
||||
|
||||
observabilityService := observability.NewService(ctx, panicHandler)
|
||||
|
||||
bridge := &Bridge{
|
||||
vault: vault,
|
||||
|
||||
@ -306,11 +308,11 @@ func newBridge(
|
||||
lastVersion: lastVersion,
|
||||
|
||||
tasks: tasks,
|
||||
syncService: syncservice.NewService(reporter, panicHandler),
|
||||
syncService: syncservice.NewService(panicHandler, observabilityService),
|
||||
|
||||
unleashService: unleashService,
|
||||
|
||||
observabilityService: observability.NewService(ctx, panicHandler),
|
||||
observabilityService: observabilityService,
|
||||
|
||||
notificationStore: notifications.NewStore(locator.ProvideNotificationsCachePath),
|
||||
}
|
||||
@ -342,7 +344,7 @@ func newBridge(
|
||||
|
||||
bridge.unleashService.Run()
|
||||
|
||||
bridge.observabilityService.Run()
|
||||
bridge.observabilityService.Run(bridge)
|
||||
|
||||
return bridge, nil
|
||||
}
|
||||
@ -710,5 +712,13 @@ func (bridge *Bridge) GetFeatureFlagValue(key string) bool {
|
||||
}
|
||||
|
||||
func (bridge *Bridge) PushObservabilityMetric(metric proton.ObservabilityMetric) {
|
||||
bridge.observabilityService.AddMetric(metric)
|
||||
bridge.observabilityService.AddMetrics(metric)
|
||||
}
|
||||
|
||||
func (bridge *Bridge) PushDistinctObservabilityMetrics(errType observability.DistinctionErrorTypeEnum, metrics ...proton.ObservabilityMetric) {
|
||||
bridge.observabilityService.AddDistinctMetrics(errType, metrics...)
|
||||
}
|
||||
|
||||
func (bridge *Bridge) ModifyObservabilityHeartbeatInterval(duration time.Duration) {
|
||||
bridge.observabilityService.ModifyHeartbeatInterval(duration)
|
||||
}
|
||||
|
||||
49
internal/bridge/mocks/observability_mocks.go
Normal file
49
internal/bridge/mocks/observability_mocks.go
Normal file
@ -0,0 +1,49 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/services/observability"
|
||||
"github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
type MockObservabilitySender struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockObservabilitySenderRecorder
|
||||
}
|
||||
|
||||
type MockObservabilitySenderRecorder struct {
|
||||
mock *MockObservabilitySender
|
||||
}
|
||||
|
||||
func NewMockObservabilitySender(ctrl *gomock.Controller) *MockObservabilitySender {
|
||||
mock := &MockObservabilitySender{ctrl: ctrl}
|
||||
mock.recorder = &MockObservabilitySenderRecorder{mock: mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
func (m *MockObservabilitySender) EXPECT() *MockObservabilitySenderRecorder { return m.recorder }
|
||||
|
||||
func (m *MockObservabilitySender) AddDistinctMetrics(errType observability.DistinctionErrorTypeEnum, _ ...proton.ObservabilityMetric) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "AddDistinctMetrics", errType)
|
||||
}
|
||||
|
||||
func (m *MockObservabilitySender) AddMetrics(metrics ...proton.ObservabilityMetric) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "AddMetrics", metrics)
|
||||
}
|
||||
|
||||
func (mr *MockObservabilitySenderRecorder) AddDistinctMetrics(errType observability.DistinctionErrorTypeEnum, _ ...proton.ObservabilityMetric) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
|
||||
"AddDistinctMetrics",
|
||||
reflect.TypeOf((*MockObservabilitySender)(nil).AddDistinctMetrics),
|
||||
errType)
|
||||
}
|
||||
|
||||
func (mr *MockObservabilitySenderRecorder) AddMetrics(metrics ...proton.ObservabilityMetric) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddMetrics", reflect.TypeOf((*MockObservabilitySender)(nil).AddMetrics), metrics)
|
||||
}
|
||||
@ -95,3 +95,70 @@ func TestBridge_Observability(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestBridge_Observability_Heartbeat(t *testing.T) {
|
||||
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
|
||||
throttlePeriod := time.Millisecond * 300
|
||||
observability.ModifyThrottlePeriod(throttlePeriod)
|
||||
|
||||
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||
require.NoError(t, getErr(bridge.LoginFull(ctx, username, password, nil, nil)))
|
||||
bridge.ModifyObservabilityHeartbeatInterval(throttlePeriod)
|
||||
|
||||
require.Equal(t, 0, len(s.GetObservabilityStatistics().Metrics))
|
||||
time.Sleep(time.Millisecond * 150)
|
||||
require.Equal(t, 0, len(s.GetObservabilityStatistics().Metrics))
|
||||
time.Sleep(time.Millisecond * 200)
|
||||
require.Equal(t, 1, len(s.GetObservabilityStatistics().Metrics))
|
||||
time.Sleep(time.Millisecond * 350)
|
||||
require.Equal(t, 2, len(s.GetObservabilityStatistics().Metrics))
|
||||
time.Sleep(time.Millisecond * 350)
|
||||
require.Equal(t, 3, len(s.GetObservabilityStatistics().Metrics))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestBridge_Observability_UserMetric(t *testing.T) {
|
||||
testMetric := proton.ObservabilityMetric{
|
||||
Name: "test1",
|
||||
Version: 1,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Data: nil,
|
||||
}
|
||||
|
||||
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
|
||||
userMetricPeriod := time.Millisecond * 200
|
||||
heartbeatPeriod := time.Second * 10
|
||||
throttlePeriod := time.Millisecond * 100
|
||||
observability.ModifyUserMetricInterval(userMetricPeriod)
|
||||
observability.ModifyThrottlePeriod(throttlePeriod)
|
||||
|
||||
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||
require.NoError(t, getErr(bridge.LoginFull(ctx, username, password, nil, nil)))
|
||||
bridge.ModifyObservabilityHeartbeatInterval(heartbeatPeriod)
|
||||
|
||||
time.Sleep(throttlePeriod)
|
||||
require.Equal(t, 0, len(s.GetObservabilityStatistics().Metrics))
|
||||
|
||||
bridge.PushDistinctObservabilityMetrics(observability.SyncError, testMetric)
|
||||
time.Sleep(throttlePeriod)
|
||||
// We're expecting two observability metrics to be sent, the actual metric + the user metric.
|
||||
require.Equal(t, 2, len(s.GetObservabilityStatistics().Metrics))
|
||||
|
||||
bridge.PushDistinctObservabilityMetrics(observability.SyncError, testMetric)
|
||||
time.Sleep(throttlePeriod)
|
||||
// We're expecting only a single metric to be sent, since the user metric update has been sent already within the predefined period.
|
||||
require.Equal(t, 3, len(s.GetObservabilityStatistics().Metrics))
|
||||
|
||||
bridge.PushDistinctObservabilityMetrics(observability.SyncError, testMetric)
|
||||
time.Sleep(throttlePeriod)
|
||||
// Two metric updates should be sent again.
|
||||
require.Equal(t, 5, len(s.GetObservabilityStatistics().Metrics))
|
||||
|
||||
bridge.PushDistinctObservabilityMetrics(observability.SyncError, testMetric)
|
||||
time.Sleep(throttlePeriod)
|
||||
// Only a single one should be sent.
|
||||
require.Equal(t, 6, len(s.GetObservabilityStatistics().Metrics))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -571,7 +571,6 @@ func (bridge *Bridge) addUserWithVault(
|
||||
isNew,
|
||||
bridge.notificationStore,
|
||||
bridge.unleashService.GetFlagValue,
|
||||
bridge.observabilityService.AddMetric,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create user: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user