mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 12:46:46 +00:00
feat(GODT-2552): Add unit test.
This commit is contained in:
committed by
Romain Le Jeune
parent
b250d49af8
commit
67b5e7f96a
1
Makefile
1
Makefile
@ -256,6 +256,7 @@ mocks:
|
||||
mockgen --package mocks github.com/ProtonMail/gluon/async PanicHandler > internal/bridge/mocks/async_mocks.go
|
||||
mockgen --package mocks github.com/ProtonMail/gluon/reporter Reporter > internal/bridge/mocks/gluon_mocks.go
|
||||
mockgen --package mocks github.com/ProtonMail/proton-bridge/v3/internal/updater Downloader,Installer > internal/updater/mocks/mocks.go
|
||||
mockgen --package mocks github.com/ProtonMail/proton-bridge/v3/internal/telemetry HeartbeatManager > internal/telemetry/mocks/mocks.go
|
||||
|
||||
lint: gofiles lint-golang lint-license lint-dependencies lint-changelog
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ func NewHeartbeat(manager HeartbeatManager, imapPort, smtpPort int, cacheDir, ke
|
||||
log: logrus.WithField("pkg", "telemetry"),
|
||||
manager: manager,
|
||||
metrics: HeartbeatData{
|
||||
MeasurementGroup: "bridge.amy.usage",
|
||||
MeasurementGroup: "bridge.any.usage",
|
||||
Event: "bridge_heartbeat",
|
||||
},
|
||||
defaultIMAPPort: imapPort,
|
||||
@ -41,7 +41,7 @@ func NewHeartbeat(manager HeartbeatManager, imapPort, smtpPort int, cacheDir, ke
|
||||
}
|
||||
|
||||
func (heartbeat *Heartbeat) SetRollout(val float64) {
|
||||
heartbeat.metrics.Values.Rollout = int(val * 100)
|
||||
heartbeat.metrics.Dimensions.Rollout = int(val * 100)
|
||||
}
|
||||
|
||||
func (heartbeat *Heartbeat) SetNbAccount(val int) {
|
||||
@ -129,7 +129,7 @@ func (heartbeat *Heartbeat) SetSMTPPort(val int) {
|
||||
}
|
||||
|
||||
func (heartbeat *Heartbeat) SetCacheLocation(val string) {
|
||||
if val != heartbeat.defaultCache {
|
||||
if val == heartbeat.defaultCache {
|
||||
heartbeat.metrics.Dimensions.CacheLocation = dimensionDefault
|
||||
} else {
|
||||
heartbeat.metrics.Dimensions.CacheLocation = dimensionCustom
|
||||
@ -137,7 +137,7 @@ func (heartbeat *Heartbeat) SetCacheLocation(val string) {
|
||||
}
|
||||
|
||||
func (heartbeat *Heartbeat) SetKeyChainPref(val string) {
|
||||
if val != heartbeat.defaultKeychain {
|
||||
if val == heartbeat.defaultKeychain {
|
||||
heartbeat.metrics.Dimensions.KeychainPref = dimensionDefault
|
||||
} else {
|
||||
heartbeat.metrics.Dimensions.KeychainPref = dimensionCustom
|
||||
@ -152,7 +152,7 @@ func (heartbeat *Heartbeat) StartSending() {
|
||||
if heartbeat.manager.IsTelemetryAvailable() {
|
||||
lastSent := heartbeat.manager.GetLastHeartbeatSent()
|
||||
now := time.Now()
|
||||
if now.Year() >= lastSent.Year() && now.YearDay() > lastSent.YearDay() {
|
||||
if now.Year() > lastSent.Year() || (now.Year() == lastSent.Year() && now.YearDay() > lastSent.YearDay()) {
|
||||
if !heartbeat.manager.SendHeartbeat(&heartbeat.metrics) {
|
||||
heartbeat.log.WithFields(logrus.Fields{
|
||||
"metrics": heartbeat.metrics,
|
||||
|
||||
97
internal/telemetry/heartbeat_test.go
Normal file
97
internal/telemetry/heartbeat_test.go
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2023 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.
|
||||
//
|
||||
// Proton Mail Bridge is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Proton Mail Bridge is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package telemetry_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/telemetry"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/telemetry/mocks"
|
||||
"github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
func TestHeartbeat_default_heartbeat(t *testing.T) {
|
||||
withHeartbeat(t, 1143, 1025, "/tmp", "defaultKeychain", func(hb *telemetry.Heartbeat, mock *mocks.MockHeartbeatManager) {
|
||||
data := telemetry.HeartbeatData{
|
||||
MeasurementGroup: "bridge.any.usage",
|
||||
Event: "bridge_heartbeat",
|
||||
Values: telemetry.HeartbeatValues{
|
||||
NbAccount: 1,
|
||||
},
|
||||
Dimensions: telemetry.HeartbeatDimensions{
|
||||
AutoUpdate: "on",
|
||||
AutoStart: "on",
|
||||
Beta: "off",
|
||||
Doh: "off",
|
||||
SplitMode: "off",
|
||||
ShowAllMail: "off",
|
||||
IMAPConnectionMode: "ssl",
|
||||
SMTPConnectionMode: "ssl",
|
||||
IMAPPort: "default",
|
||||
SMTPPort: "default",
|
||||
CacheLocation: "default",
|
||||
KeychainPref: "default",
|
||||
PrevVersion: "1.2.3",
|
||||
Rollout: 10,
|
||||
},
|
||||
}
|
||||
|
||||
mock.EXPECT().IsTelemetryAvailable().Return(true)
|
||||
mock.EXPECT().GetLastHeartbeatSent().Return(time.Date(2022, 6, 4, 0, 0, 0, 0, time.UTC))
|
||||
mock.EXPECT().SendHeartbeat(&data).Return(true)
|
||||
mock.EXPECT().SetLastHeartbeatSent(gomock.Any()).Return(nil)
|
||||
|
||||
hb.StartSending()
|
||||
})
|
||||
}
|
||||
|
||||
func TestHeartbeat_already_sent_heartbeat(t *testing.T) {
|
||||
withHeartbeat(t, 1143, 1025, "/tmp", "defaultKeychain", func(hb *telemetry.Heartbeat, mock *mocks.MockHeartbeatManager) {
|
||||
mock.EXPECT().IsTelemetryAvailable().Return(true)
|
||||
mock.EXPECT().GetLastHeartbeatSent().Return(time.Now().Truncate(24 * time.Hour))
|
||||
|
||||
hb.StartSending()
|
||||
})
|
||||
}
|
||||
|
||||
func withHeartbeat(t *testing.T, imap, smtp int, cache, keychain string, tests func(hb *telemetry.Heartbeat, mock *mocks.MockHeartbeatManager)) {
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
|
||||
manager := mocks.NewMockHeartbeatManager(ctl)
|
||||
heartbeat := telemetry.NewHeartbeat(manager, imap, smtp, cache, keychain)
|
||||
|
||||
heartbeat.SetRollout(0.1)
|
||||
heartbeat.SetNbAccount(1)
|
||||
heartbeat.SetSplitMode(false)
|
||||
heartbeat.SetAutoStart(true)
|
||||
heartbeat.SetAutoUpdate(true)
|
||||
heartbeat.SetBeta("stable")
|
||||
heartbeat.SetDoh(false)
|
||||
heartbeat.SetShowAllMail(false)
|
||||
heartbeat.SetIMAPConnectionMode(true)
|
||||
heartbeat.SetSMTPConnectionMode(true)
|
||||
heartbeat.SetIMAPPort(1143)
|
||||
heartbeat.SetSMTPPort(1025)
|
||||
heartbeat.SetCacheLocation("/tmp")
|
||||
heartbeat.SetKeyChainPref("defaultKeychain")
|
||||
heartbeat.SetPrevVersion("1.2.3")
|
||||
|
||||
tests(&heartbeat, manager)
|
||||
}
|
||||
92
internal/telemetry/mocks/mocks.go
Normal file
92
internal/telemetry/mocks/mocks.go
Normal file
@ -0,0 +1,92 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ProtonMail/proton-bridge/v3/internal/telemetry (interfaces: HeartbeatManager)
|
||||
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
telemetry "github.com/ProtonMail/proton-bridge/v3/internal/telemetry"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockHeartbeatManager is a mock of HeartbeatManager interface.
|
||||
type MockHeartbeatManager struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockHeartbeatManagerMockRecorder
|
||||
}
|
||||
|
||||
// MockHeartbeatManagerMockRecorder is the mock recorder for MockHeartbeatManager.
|
||||
type MockHeartbeatManagerMockRecorder struct {
|
||||
mock *MockHeartbeatManager
|
||||
}
|
||||
|
||||
// NewMockHeartbeatManager creates a new mock instance.
|
||||
func NewMockHeartbeatManager(ctrl *gomock.Controller) *MockHeartbeatManager {
|
||||
mock := &MockHeartbeatManager{ctrl: ctrl}
|
||||
mock.recorder = &MockHeartbeatManagerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockHeartbeatManager) EXPECT() *MockHeartbeatManagerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetLastHeartbeatSent mocks base method.
|
||||
func (m *MockHeartbeatManager) GetLastHeartbeatSent() time.Time {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetLastHeartbeatSent")
|
||||
ret0, _ := ret[0].(time.Time)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetLastHeartbeatSent indicates an expected call of GetLastHeartbeatSent.
|
||||
func (mr *MockHeartbeatManagerMockRecorder) GetLastHeartbeatSent() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastHeartbeatSent", reflect.TypeOf((*MockHeartbeatManager)(nil).GetLastHeartbeatSent))
|
||||
}
|
||||
|
||||
// IsTelemetryAvailable mocks base method.
|
||||
func (m *MockHeartbeatManager) IsTelemetryAvailable() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsTelemetryAvailable")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IsTelemetryAvailable indicates an expected call of IsTelemetryAvailable.
|
||||
func (mr *MockHeartbeatManagerMockRecorder) IsTelemetryAvailable() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsTelemetryAvailable", reflect.TypeOf((*MockHeartbeatManager)(nil).IsTelemetryAvailable))
|
||||
}
|
||||
|
||||
// SendHeartbeat mocks base method.
|
||||
func (m *MockHeartbeatManager) SendHeartbeat(arg0 *telemetry.HeartbeatData) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendHeartbeat", arg0)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SendHeartbeat indicates an expected call of SendHeartbeat.
|
||||
func (mr *MockHeartbeatManagerMockRecorder) SendHeartbeat(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeartbeat", reflect.TypeOf((*MockHeartbeatManager)(nil).SendHeartbeat), arg0)
|
||||
}
|
||||
|
||||
// SetLastHeartbeatSent mocks base method.
|
||||
func (m *MockHeartbeatManager) SetLastHeartbeatSent(arg0 time.Time) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SetLastHeartbeatSent", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetLastHeartbeatSent indicates an expected call of SetLastHeartbeatSent.
|
||||
func (mr *MockHeartbeatManagerMockRecorder) SetLastHeartbeatSent(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastHeartbeatSent", reflect.TypeOf((*MockHeartbeatManager)(nil).SetLastHeartbeatSent), arg0)
|
||||
}
|
||||
@ -40,7 +40,6 @@ type HeartbeatManager interface {
|
||||
}
|
||||
|
||||
type HeartbeatValues struct {
|
||||
Rollout int `json:"rollout"`
|
||||
NbAccount int `json:"nb_account"`
|
||||
}
|
||||
|
||||
@ -58,6 +57,7 @@ type HeartbeatDimensions struct {
|
||||
CacheLocation string `json:"cache_location"`
|
||||
KeychainPref string `json:"keychain_pref"`
|
||||
PrevVersion string `json:"prev_version"`
|
||||
Rollout int `json:"rollout"`
|
||||
}
|
||||
|
||||
type HeartbeatData struct {
|
||||
|
||||
Reference in New Issue
Block a user