forked from Silverfish/proton-bridge
feat(GODT-2554): Compute telemetry availability from API UserSettings.
This commit is contained in:
@ -477,6 +477,18 @@ func (bridge *Bridge) Close(ctx context.Context) {
|
|||||||
bridge.watchers = nil
|
bridge.watchers = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bridge *Bridge) ComputeTelemetry() bool {
|
||||||
|
var telemetry = true
|
||||||
|
|
||||||
|
safe.RLock(func() {
|
||||||
|
for _, user := range bridge.users {
|
||||||
|
telemetry = telemetry && user.IsTelemetryEnabled(context.Background())
|
||||||
|
}
|
||||||
|
}, bridge.usersLock)
|
||||||
|
|
||||||
|
return telemetry
|
||||||
|
}
|
||||||
|
|
||||||
func (bridge *Bridge) publish(event events.Event) {
|
func (bridge *Bridge) publish(event events.Event) {
|
||||||
bridge.watchersLock.RLock()
|
bridge.watchersLock.RLock()
|
||||||
defer bridge.watchersLock.RUnlock()
|
defer bridge.watchersLock.RUnlock()
|
||||||
|
|||||||
@ -591,6 +591,16 @@ func (user *User) Close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsTelemetryEnabled check if the telemetry is enabled or disabled for this user.
|
||||||
|
func (user *User) IsTelemetryEnabled(ctx context.Context) bool {
|
||||||
|
settings, err := user.client.GetUserSettings(ctx)
|
||||||
|
if err != nil {
|
||||||
|
user.log.WithError(err).Warn("Failed to retrieve API user Settings")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return settings.Telemetry == proton.SettingEnabled
|
||||||
|
}
|
||||||
|
|
||||||
// initUpdateCh initializes the user's update channels in the given address mode.
|
// initUpdateCh initializes the user's update channels in the given address mode.
|
||||||
// It is assumed that user.apiAddrs and user.updateCh are already locked.
|
// It is assumed that user.apiAddrs and user.updateCh are already locked.
|
||||||
func (user *User) initUpdateCh(mode vault.AddressMode) {
|
func (user *User) initUpdateCh(mode vault.AddressMode) {
|
||||||
|
|||||||
@ -80,6 +80,23 @@ func TestUser_AddressMode(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUser_Telemetry(t *testing.T) {
|
||||||
|
withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
|
||||||
|
withAccount(t, s, "username", "password", []string{}, func(string, []string) {
|
||||||
|
withUser(t, ctx, s, m, "username", "password", func(user *User) {
|
||||||
|
// By default, user should have Telemetry enabled.
|
||||||
|
telemetry := user.IsTelemetryEnabled(ctx)
|
||||||
|
require.Equal(t, true, telemetry)
|
||||||
|
|
||||||
|
user.client.Close()
|
||||||
|
// If telemetry cannot be retrieved it is disabled.
|
||||||
|
telemetry = user.IsTelemetryEnabled(ctx)
|
||||||
|
require.Equal(t, false, telemetry)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *proton.Manager)) { //nolint:revive
|
func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *proton.Manager)) { //nolint:revive
|
||||||
server := server.New()
|
server := server.New()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|||||||
@ -153,6 +153,8 @@ func TestFeatures(testingT *testing.T) {
|
|||||||
ctx.Step(`^bridge sends an update not available event$`, s.bridgeSendsAnUpdateNotAvailableEvent)
|
ctx.Step(`^bridge sends an update not available event$`, s.bridgeSendsAnUpdateNotAvailableEvent)
|
||||||
ctx.Step(`^bridge sends a forced update event$`, s.bridgeSendsAForcedUpdateEvent)
|
ctx.Step(`^bridge sends a forced update event$`, s.bridgeSendsAForcedUpdateEvent)
|
||||||
ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage)
|
ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage)
|
||||||
|
ctx.Step(`^bridge telemetry feature is enabled$`, s.bridgeTelemetryFeatureEnabled)
|
||||||
|
ctx.Step(`^bridge telemetry feature is disabled$`, s.bridgeTelemetryFeatureDisabled)
|
||||||
|
|
||||||
// ==== FRONTEND ====
|
// ==== FRONTEND ====
|
||||||
ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion)
|
ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion)
|
||||||
@ -166,6 +168,7 @@ func TestFeatures(testingT *testing.T) {
|
|||||||
ctx.Step(`^user "([^"]*)" is listed but not connected$`, s.userIsListedButNotConnected)
|
ctx.Step(`^user "([^"]*)" is listed but not connected$`, s.userIsListedButNotConnected)
|
||||||
ctx.Step(`^user "([^"]*)" is not listed$`, s.userIsNotListed)
|
ctx.Step(`^user "([^"]*)" is not listed$`, s.userIsNotListed)
|
||||||
ctx.Step(`^user "([^"]*)" finishes syncing$`, s.userFinishesSyncing)
|
ctx.Step(`^user "([^"]*)" finishes syncing$`, s.userFinishesSyncing)
|
||||||
|
ctx.Step(`^user "([^"]*)" has telemetry set to (\d+)$`, s.userHasTelemetrySetTo)
|
||||||
|
|
||||||
// ==== IMAP ====
|
// ==== IMAP ====
|
||||||
ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)"$`, s.userConnectsIMAPClient)
|
ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)"$`, s.userConnectsIMAPClient)
|
||||||
|
|||||||
@ -284,6 +284,22 @@ func (s *scenario) bridgeReportsMessage(message string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *scenario) bridgeTelemetryFeatureEnabled() error {
|
||||||
|
return s.checkTelemetry(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scenario) bridgeTelemetryFeatureDisabled() error {
|
||||||
|
return s.checkTelemetry(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scenario) checkTelemetry(expect bool) error {
|
||||||
|
res := s.t.bridge.ComputeTelemetry()
|
||||||
|
if res != expect {
|
||||||
|
return fmt.Errorf("expected telemetry feature %v but got %v ", expect, res)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *scenario) theUserHidesAllMail() error {
|
func (s *scenario) theUserHidesAllMail() error {
|
||||||
return s.t.bridge.SetShowAllMail(false)
|
return s.t.bridge.SetShowAllMail(false)
|
||||||
}
|
}
|
||||||
|
|||||||
18
tests/features/user/telemetry.feature
Normal file
18
tests/features/user/telemetry.feature
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
Feature: Bridge send usage metrics
|
||||||
|
Background:
|
||||||
|
Given there exists an account with username "[user:user1]" and password "password"
|
||||||
|
And there exists an account with username "[user:user2]" and password "password"
|
||||||
|
And bridge starts
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Telemetry availability - No user
|
||||||
|
Then bridge telemetry feature is enabled
|
||||||
|
|
||||||
|
Scenario: Telemetry availability - Multi user
|
||||||
|
When the user logs in with username "[user:user1]" and password "password"
|
||||||
|
And user "[user:user1]" finishes syncing
|
||||||
|
Then bridge telemetry feature is enabled
|
||||||
|
When the user logs in with username "[user:user2]" and password "password"
|
||||||
|
And user "[user:user2]" finishes syncing
|
||||||
|
When user "[user:user2]" has telemetry set to 0
|
||||||
|
Then bridge telemetry feature is disabled
|
||||||
@ -414,6 +414,18 @@ func (s *scenario) userFinishesSyncing(username string) error {
|
|||||||
return s.bridgeSendsSyncStartedAndFinishedEventsForUser(username)
|
return s.bridgeSendsSyncStartedAndFinishedEventsForUser(username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *scenario) userHasTelemetrySetTo(username string, telemetry int) error {
|
||||||
|
return s.t.withClientPass(context.Background(), username, s.t.getUserByName(username).userPass, func(ctx context.Context, c *proton.Client) error {
|
||||||
|
var req proton.SetTelemetryReq
|
||||||
|
req.Telemetry = proton.SettingsBool(telemetry)
|
||||||
|
_, err := c.SetUserSettingsTelemetry(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (s *scenario) addAdditionalAddressToAccount(username, address string, disabled bool) error {
|
func (s *scenario) addAdditionalAddressToAccount(username, address string, disabled bool) error {
|
||||||
userID := s.t.getUserByName(username).getUserID()
|
userID := s.t.getUserByName(username).getUserID()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user