[MM-32390] Config logic refactor (#17578)

* Replace config generator

* Cleanup

* Some renaming and docs additions to add clarity

* Cleanup logging related methods

* Cleanup emitter

* Fix TestDefaultsGenerator

* Move feature flags synchronization logic out of config package

* Remove unnecessary util functions

* Simplify load/set logic

* Refine semantics and add some test to cover them

* Remove unnecessary deep copies

* Improve logic further

* Fix license header

* Review file store tests

* Fix test

* Fix test

* Avoid additional write during initialization

* More consistent naming

* Update app/feature_flags.go

Co-authored-by: Christopher Speller <crspeller@gmail.com>

* Update config/store.go

Co-authored-by: Christopher Speller <crspeller@gmail.com>

* Update config/store.go

Co-authored-by: Christopher Speller <crspeller@gmail.com>

* Update config/store.go

Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>

* Move FF synchronizer to its own package

* Remove unidiomatic use of sync.Once

* Add some comments

* Rename function

* More comment

Co-authored-by: Christopher Speller <crspeller@gmail.com>
Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>
Этот коммит содержится в:
Claudio Costa
2021-05-19 13:30:26 +02:00
коммит произвёл GitHub
родитель b810a40062
Коммит 3681cd3688
37 изменённых файлов: 819 добавлений и 668 удалений

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package config_test
package config
import (
"fmt"
@@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-server/v5/config"
"github.com/mattermost/mattermost-server/v5/model"
)
@@ -26,16 +25,16 @@ func TestGetClientConfig(t *testing.T) {
"unlicensed",
&model.Config{
EmailSettings: model.EmailSettings{
EmailNotificationContentsType: sToP(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
EmailNotificationContentsType: model.NewString(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
},
ThemeSettings: model.ThemeSettings{
// Ignored, since not licensed.
AllowCustomThemes: bToP(false),
AllowCustomThemes: model.NewBool(false),
},
ServiceSettings: model.ServiceSettings{
WebsocketURL: sToP("ws://mattermost.example.com:8065"),
WebsocketPort: iToP(80),
WebsocketSecurePort: iToP(443),
WebsocketURL: model.NewString("ws://mattermost.example.com:8065"),
WebsocketPort: model.NewInt(80),
WebsocketSecurePort: model.NewInt(443),
},
},
"",
@@ -54,17 +53,17 @@ func TestGetClientConfig(t *testing.T) {
"licensed, but not for theme management",
&model.Config{
EmailSettings: model.EmailSettings{
EmailNotificationContentsType: sToP(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
EmailNotificationContentsType: model.NewString(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
},
ThemeSettings: model.ThemeSettings{
// Ignored, since not licensed.
AllowCustomThemes: bToP(false),
AllowCustomThemes: model.NewBool(false),
},
},
"tag1",
&model.License{
Features: &model.Features{
ThemeManagement: bToP(false),
ThemeManagement: model.NewBool(false),
},
},
map[string]string{
@@ -77,16 +76,16 @@ func TestGetClientConfig(t *testing.T) {
"licensed for theme management",
&model.Config{
EmailSettings: model.EmailSettings{
EmailNotificationContentsType: sToP(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
EmailNotificationContentsType: model.NewString(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
},
ThemeSettings: model.ThemeSettings{
AllowCustomThemes: bToP(false),
AllowCustomThemes: model.NewBool(false),
},
},
"tag2",
&model.License{
Features: &model.Features{
ThemeManagement: bToP(true),
ThemeManagement: model.NewBool(true),
},
},
map[string]string{
@@ -99,13 +98,13 @@ func TestGetClientConfig(t *testing.T) {
"licensed for enforcement",
&model.Config{
ServiceSettings: model.ServiceSettings{
EnforceMultifactorAuthentication: bToP(true),
EnforceMultifactorAuthentication: model.NewBool(true),
},
},
"tag1",
&model.License{
Features: &model.Features{
MFA: bToP(true),
MFA: model.NewBool(true),
},
},
map[string]string{
@@ -116,7 +115,7 @@ func TestGetClientConfig(t *testing.T) {
"experimental channel organization enabled",
&model.Config{
ServiceSettings: model.ServiceSettings{
ExperimentalChannelOrganization: bToP(true),
ExperimentalChannelOrganization: model.NewBool(true),
},
},
"tag1",
@@ -129,8 +128,8 @@ func TestGetClientConfig(t *testing.T) {
"experimental channel organization disabled, but experimental group unread channels on",
&model.Config{
ServiceSettings: model.ServiceSettings{
ExperimentalChannelOrganization: bToP(false),
ExperimentalGroupUnreadChannels: sToP(model.GROUP_UNREAD_CHANNELS_DEFAULT_ON),
ExperimentalChannelOrganization: model.NewBool(false),
ExperimentalGroupUnreadChannels: model.NewString(model.GROUP_UNREAD_CHANNELS_DEFAULT_ON),
},
},
"tag1",
@@ -143,7 +142,7 @@ func TestGetClientConfig(t *testing.T) {
"default marketplace",
&model.Config{
PluginSettings: model.PluginSettings{
MarketplaceUrl: sToP(model.PLUGIN_SETTINGS_DEFAULT_MARKETPLACE_URL),
MarketplaceUrl: model.NewString(model.PLUGIN_SETTINGS_DEFAULT_MARKETPLACE_URL),
},
},
"tag1",
@@ -156,7 +155,7 @@ func TestGetClientConfig(t *testing.T) {
"non-default marketplace",
&model.Config{
PluginSettings: model.PluginSettings{
MarketplaceUrl: sToP("http://example.com"),
MarketplaceUrl: model.NewString("http://example.com"),
},
},
"tag1",
@@ -169,7 +168,7 @@ func TestGetClientConfig(t *testing.T) {
"enable ShowFullName prop",
&model.Config{
PrivacySettings: model.PrivacySettings{
ShowFullName: bToP(true),
ShowFullName: model.NewBool(true),
},
},
"tag1",
@@ -190,7 +189,7 @@ func TestGetClientConfig(t *testing.T) {
testCase.license.Features.SetDefaults()
}
configMap := config.GenerateClientConfig(testCase.config, testCase.telemetryID, testCase.license)
configMap := GenerateClientConfig(testCase.config, testCase.telemetryID, testCase.license)
for expectedField, expectedValue := range testCase.expectedFields {
actualValue, ok := configMap[expectedField]
if assert.True(t, ok, fmt.Sprintf("config does not contain %v", expectedField)) {
@@ -214,16 +213,16 @@ func TestGetLimitedClientConfig(t *testing.T) {
"unlicensed",
&model.Config{
EmailSettings: model.EmailSettings{
EmailNotificationContentsType: sToP(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
EmailNotificationContentsType: model.NewString(model.EMAIL_NOTIFICATION_CONTENTS_FULL),
},
ThemeSettings: model.ThemeSettings{
// Ignored, since not licensed.
AllowCustomThemes: bToP(false),
AllowCustomThemes: model.NewBool(false),
},
ServiceSettings: model.ServiceSettings{
WebsocketURL: sToP("ws://mattermost.example.com:8065"),
WebsocketPort: iToP(80),
WebsocketSecurePort: iToP(443),
WebsocketURL: model.NewString("ws://mattermost.example.com:8065"),
WebsocketPort: model.NewInt(80),
WebsocketSecurePort: model.NewInt(443),
},
},
"",
@@ -240,11 +239,11 @@ func TestGetLimitedClientConfig(t *testing.T) {
"password settings",
&model.Config{
PasswordSettings: model.PasswordSettings{
MinimumLength: iToP(15),
Lowercase: bToP(true),
Uppercase: bToP(true),
Number: bToP(true),
Symbol: bToP(false),
MinimumLength: model.NewInt(15),
Lowercase: model.NewBool(true),
Uppercase: model.NewBool(true),
Number: model.NewBool(true),
Symbol: model.NewBool(false),
},
},
"",
@@ -282,7 +281,7 @@ func TestGetLimitedClientConfig(t *testing.T) {
testCase.license.Features.SetDefaults()
}
configMap := config.GenerateLimitedClientConfig(testCase.config, testCase.telemetryID, testCase.license)
configMap := GenerateLimitedClientConfig(testCase.config, testCase.telemetryID, testCase.license)
for expectedField, expectedValue := range testCase.expectedFields {
actualValue, ok := configMap[expectedField]
if assert.True(t, ok, fmt.Sprintf("config does not contain %v", expectedField)) {
@@ -292,15 +291,3 @@ func TestGetLimitedClientConfig(t *testing.T) {
})
}
}
func sToP(s string) *string {
return &s
}
func bToP(b bool) *bool {
return &b
}
func iToP(i int) *int {
return &i
}