Enable products for tests (#22757)

* Enable products for channels tests

* increase unit test timeout; check IsConfigReadOnly

* make app-layers

* Avoid loading boards tempaltes between tests to improve speed

* Fix delete query to be compatible with both databases

* Avoid preserving the templates for boards store tests

* Run all tests in one command

* Revert "Run all tests in one command"

This reverts commit 0330f7cd8f.

* concurrent pkg group tests in CI

* Revert "Revert "Run all tests in one command""

This reverts commit 73892fec77.

* Revert "concurrent pkg group tests in CI"

This reverts commit 550fb6cdd4.

* try testing 3 subsets of packages concurrently to improve time taken

* Revert "try testing 3 subsets of packages concurrently to improve time taken"

This reverts commit 97475f3c4e.

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: wiggin77 <wiggin77@warpmail.net>
This commit is contained in:
Miguel de la Cruz 2023-04-18 13:58:33 +02:00 committed by GitHub
parent a8d79ec3da
commit 067e36c23c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 377 additions and 105 deletions

View File

@ -132,9 +132,7 @@ DIST_PATH_WIN=$(DIST_ROOT)/windows/mattermost
TESTS=.
# Packages lists
TE_PACKAGES=$(shell $(GO) list ./... | grep -vE 'server/v8/playbooks|server/v8/boards')
BOARDS_PACKAGES=$(shell $(GO) list ./... | grep -E 'server/v8/boards')
PLAYBOOKS_PACKAGES=$(shell $(GO) list ./... | grep -E 'server/v8/playbooks')
SUITE_PACKAGES=$(shell $(GO) list ./...)
TEMPLATES_DIR=templates
@ -170,9 +168,9 @@ endif
EE_PACKAGES=$(shell $(GO) list $(BUILD_ENTERPRISE_DIR)/...)
ifeq ($(BUILD_ENTERPRISE_READY),true)
ALL_PACKAGES=$(TE_PACKAGES) $(BOARDS_PACKAGES) $(PLAYBOOKS_PACKAGES) $(EE_PACKAGES)
ALL_PACKAGES=$(SUITE_PACKAGES) $(EE_PACKAGES)
else
ALL_PACKAGES=$(TE_PACKAGES) $(BOARDS_PACKAGES) $(PLAYBOOKS_PACKAGES)
ALL_PACKAGES=$(SUITE_PACKAGES)
endif
all: run ## Alias for 'run'.
@ -412,7 +410,7 @@ go-junit-report:
test-compile: ## Compile tests.
@echo COMPILE TESTS
for package in $(TE_PACKAGES) $(BOARDS_PACKAGES) $(PLAYBOOKS_PACKAGES) $(EE_PACKAGES); do \
for package in $(SUITE_PACKAGES) $(EE_PACKAGES); do \
$(GO) test $(GOFLAGS) -c $$package; \
done
@ -450,9 +448,7 @@ else
endif
test-server-race: test-server-pre
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=true ./scripts/test.sh "$(GO)" "-race $(GOFLAGS)" "$(TE_PACKAGES) $(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "90m" "atomic"
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=false ./scripts/test.sh "$(GO)" "-race $(GOFLAGS)" "$(BOARDS_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "90m" "atomic"
MM_DISABLE_PLAYBOOKS=false MM_DISABLE_BOARDS=true ./scripts/test.sh "$(GO)" "-race $(GOFLAGS)" "$(PLAYBOOKS_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "90m" "atomic"
./scripts/test.sh "$(GO)" "-race $(GOFLAGS)" "$(SUITE_PACKAGES) $(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "90m" "atomic"
ifneq ($(IS_CI),true)
ifneq ($(MM_NO_DOCKER),true)
ifneq ($(TEMP_DOCKER_SERVICES),)
@ -463,9 +459,7 @@ ifneq ($(IS_CI),true)
endif
test-server: test-server-pre
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=true ./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(TE_PACKAGES) $(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "45m" "count"
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=false ./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(BOARDS_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "45m" "count"
MM_DISABLE_PLAYBOOKS=false MM_DISABLE_BOARDS=true ./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(PLAYBOOKS_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "45m" "count"
./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(SUITE_PACKAGES) $(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "90m" "count"
ifneq ($(IS_CI),true)
ifneq ($(MM_NO_DOCKER),true)
ifneq ($(TEMP_DOCKER_SERVICES),)
@ -477,19 +471,15 @@ endif
test-server-ee: check-prereqs-enterprise start-docker go-junit-report do-cover-file ## Runs EE tests.
@echo Running only EE tests
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=true ./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "20m" "count"
./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(EE_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" "20m" "count"
test-server-quick: check-prereqs-enterprise ## Runs only quick tests.
ifeq ($(BUILD_ENTERPRISE_READY),true)
@echo Running all tests
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=true $(GO) test $(GOFLAGS) -short $(TE_PACKAGES) $(EE_PACKAGES)
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=false $(GO) test $(GOFLAGS) -short $(BOARDS_PACKAGES)
MM_DISABLE_PLAYBOOKS=false MM_DISABLE_BOARDS=true $(GO) test $(GOFLAGS) -short $(PLAYBOOKS_PACKAGES)
$(GO) test $(GOFLAGS) -short $(SUITE_PACKAGES) $(EE_PACKAGES)
else
@echo Running only TE tests
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=true $(GO) test $(GOFLAGS) -short $(TE_PACKAGES)
MM_DISABLE_PLAYBOOKS=true MM_DISABLE_BOARDS=false $(GO) test $(GOFLAGS) -short $(BOARDS_PACKAGES)
MM_DISABLE_PLAYBOOKS=false MM_DISABLE_BOARDS=true $(GO) test $(GOFLAGS) -short $(PLAYBOOKS_PACKAGES)
$(GO) test $(GOFLAGS) -short $(SUITE_PACKAGES)
endif
internal-test-web-client: ## Runs web client tests.

View File

@ -20,11 +20,13 @@ const (
botDescription = "Created by Boards plugin."
)
var FocalboardBot = &mm_model.Bot{
Username: botUsername,
DisplayName: botDisplayname,
Description: botDescription,
OwnerId: SystemUserID,
func GetDefaultFocalboardBot() *mm_model.Bot {
return &mm_model.Bot{
Username: botUsername,
DisplayName: botDisplayname,
Description: botDescription,
OwnerId: SystemUserID,
}
}
type ServicesAPI interface {

View File

@ -66,7 +66,7 @@ func createSubscriptionsNotifyBackend(params notifyBackendParams) (*notifysubscr
}
func createDelivery(servicesAPI model.ServicesAPI, serverRoot string) (*plugindelivery.PluginDelivery, error) {
bot := model.FocalboardBot
bot := model.GetDefaultFocalboardBot()
botID, err := servicesAPI.EnsureBot(bot)
if err != nil {

View File

@ -70,9 +70,10 @@ func New(dbType string, db *sql.DB, store store.Store, logger mlog.LoggerIFace,
return layer, nil
}
// Shutdown close the connection with the store.
// For MattermostAuthLayer we don't close the database connection
// because it's directly managed by the platform
func (s *MattermostAuthLayer) Shutdown() error {
return s.Store.Shutdown()
return nil
}
func (s *MattermostAuthLayer) GetRegisteredUserCount() (int, error) {
@ -1218,7 +1219,7 @@ func (s *MattermostAuthLayer) GetChannel(teamID, channelID string) (*mm_model.Ch
func (s *MattermostAuthLayer) getBoardsBotID() (string, error) {
if boardsBotID == "" {
var err error
boardsBotID, err = s.servicesAPI.EnsureBot(model.FocalboardBot)
boardsBotID, err = s.servicesAPI.EnsureBot(model.GetDefaultFocalboardBot())
if err != nil {
s.logger.Error("failed to ensure boards bot", mlog.Err(err))
return "", err

View File

@ -24,11 +24,11 @@ func TestGetBoardsBotID(t *testing.T) {
mmAuthLayer, _ := New("test", nil, nil, mlog.CreateConsoleTestLogger(true, mlog.LvlError), servicesAPI, "")
servicesAPI.EXPECT().EnsureBot(model.FocalboardBot).Return("", errTest)
servicesAPI.EXPECT().EnsureBot(model.GetDefaultFocalboardBot()).Return("", errTest)
_, err := mmAuthLayer.getBoardsBotID()
require.NotEmpty(t, err)
servicesAPI.EXPECT().EnsureBot(model.FocalboardBot).Return("TestBotID", nil).Times(1)
servicesAPI.EXPECT().EnsureBot(model.GetDefaultFocalboardBot()).Return("TestBotID", nil).Times(1)
botID, err := mmAuthLayer.getBoardsBotID()
require.Empty(t, err)
require.NotEmpty(t, botID)

View File

@ -199,6 +199,10 @@ func (s *SQLStore) DBVersion() string {
return version
}
// dropAllTables deletes the contents of all the database tables
// except the schema_migrations table with the intention of cleaning
// the state for the next text to execute without having to run the
// migrations.
func (s *SQLStore) dropAllTables(db sq.BaseRunner) error {
if s.DBType() == model.PostgresDBType {
_, err := db.Exec(`DO

View File

@ -93,7 +93,9 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent
panic("failed to initialize memory store: " + err.Error())
}
memoryConfig := &model.Config{}
memoryConfig := &model.Config{
SqlSettings: *mainHelper.GetSQLSettings(),
}
memoryConfig.SetDefaults()
*memoryConfig.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins")
*memoryConfig.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp")
@ -287,6 +289,7 @@ func SetupConfig(tb testing.TB, updateConfig func(cfg *model.Config)) *TestHelpe
dbStore := mainHelper.GetStore()
dbStore.DropAllTables()
dbStore.MarkSystemRanUnitTests()
mainHelper.PreloadBoardsMigrationsIfNeeded()
searchEngine := mainHelper.GetSearchEngine()
th := setupTestHelper(dbStore, searchEngine, false, true, updateConfig, nil)
th.InitLogin()
@ -294,7 +297,8 @@ func SetupConfig(tb testing.TB, updateConfig func(cfg *model.Config)) *TestHelpe
}
func SetupConfigWithStoreMock(tb testing.TB, updateConfig func(cfg *model.Config)) *TestHelper {
th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, false, false, updateConfig, nil)
setupOptions := []app.Option{app.SkipProductsInitialization()}
th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, false, false, updateConfig, setupOptions)
statusMock := mocks.StatusStore{}
statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil)
statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil)
@ -308,7 +312,8 @@ func SetupConfigWithStoreMock(tb testing.TB, updateConfig func(cfg *model.Config
}
func SetupWithStoreMock(tb testing.TB) *TestHelper {
th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, false, false, nil, nil)
setupOptions := []app.Option{app.SkipProductsInitialization()}
th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, false, false, nil, setupOptions)
statusMock := mocks.StatusStore{}
statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil)
statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil)
@ -322,7 +327,8 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper {
}
func SetupEnterpriseWithStoreMock(tb testing.TB, options ...app.Option) *TestHelper {
th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, true, false, nil, options)
setupOptions := append(options, app.SkipProductsInitialization())
th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, true, false, nil, setupOptions)
statusMock := mocks.StatusStore{}
statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil)
statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil)
@ -479,6 +485,14 @@ func (th *TestHelper) InitBasic() *TestHelper {
return th
}
func (th *TestHelper) DeleteBots() *TestHelper {
preexistingBots, _ := th.App.GetBots(&model.BotGetOptions{Page: 0, PerPage: 100})
for _, bot := range preexistingBots {
th.App.PermanentDeleteBot(bot.UserId)
}
return th
}
func (th *TestHelper) waitForConnectivity() {
for i := 0; i < 1000; i++ {
conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%v", th.App.Srv().ListenAddr.Port))

View File

@ -297,11 +297,10 @@ func TestPatchBot(t *testing.T) {
require.NoError(t, err)
CheckOKStatus(t, resp)
bots, resp, err := th.Client.GetBots(0, 2, "")
bot, resp, err := th.Client.GetBot(createdBot.UserId, "")
require.NoError(t, err)
CheckOKStatus(t, resp)
require.Len(t, bots, 1)
require.Equal(t, []*model.Bot{patchedBot}, bots)
require.Equal(t, patchedBot, bot)
})
t.Run("patch my bot without permission", func(t *testing.T) {
@ -630,7 +629,7 @@ func TestGetBot(t *testing.T) {
}
func TestGetBots(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t).InitBasic().DeleteBots()
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {

View File

@ -4140,6 +4140,12 @@ func TestGetChannelModerations(t *testing.T) {
scheme.DefaultChannelGuestRole = ""
mockStore := mocks.Store{}
// Playbooks DB job requires a plugin mock
pluginStore := mocks.PluginStore{}
pluginStore.On("List", mock.Anything, mock.Anything, mock.Anything).Return([]string{}, nil)
mockStore.On("Plugin").Return(&pluginStore)
mockSchemeStore := mocks.SchemeStore{}
mockSchemeStore.On("Get", mock.Anything).Return(scheme, nil)
mockStore.On("Scheme").Return(&mockSchemeStore)
@ -4282,6 +4288,12 @@ func TestPatchChannelModerations(t *testing.T) {
scheme.DefaultChannelGuestRole = ""
mockStore := mocks.Store{}
// Playbooks DB job requires a plugin mock
pluginStore := mocks.PluginStore{}
pluginStore.On("List", mock.Anything, mock.Anything, mock.Anything).Return([]string{}, nil)
mockStore.On("Plugin").Return(&pluginStore)
mockSchemeStore := mocks.SchemeStore{}
mockSchemeStore.On("Get", mock.Anything).Return(scheme, nil)
mockSchemeStore.On("Save", mock.Anything).Return(scheme, nil)
@ -4340,7 +4352,6 @@ func TestPatchChannelModerations(t *testing.T) {
require.Equal(t, moderation.Roles.Members.Enabled, true)
}
})
}
func TestGetChannelMemberCountsByGroup(t *testing.T) {

View File

@ -1541,6 +1541,12 @@ func TestGetFlaggedPostsForUser(t *testing.T) {
mockStore.On("License").Return(th.App.Srv().Store().License())
mockStore.On("Role").Return(th.App.Srv().Store().Role())
mockStore.On("Close").Return(nil)
// Playbooks DB job requires a plugin mock
pluginStore := mocks.PluginStore{}
pluginStore.On("List", mock.Anything, mock.Anything, mock.Anything).Return([]string{}, nil)
mockStore.On("Plugin").Return(&pluginStore)
th.App.Srv().SetStore(&mockStore)
_, resp, err = th.SystemAdminClient.GetFlaggedPostsForUser(user.Id, 0, 10)

View File

@ -2714,7 +2714,7 @@ func TestGetUsersInTeam(t *testing.T) {
}
func TestGetUsersNotInTeam(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t).InitBasic().DeleteBots()
defer th.TearDown()
teamId := th.BasicTeam.Id

View File

@ -892,6 +892,7 @@ type AppIface interface {
InviteNewUsersToTeam(emailList []string, teamID, senderId string) *model.AppError
InviteNewUsersToTeamGracefully(memberInvite *model.MemberInvite, teamID, senderId string, reminderInterval string) ([]*model.EmailInviteWithError, *model.AppError)
IsCRTEnabledForUser(c request.CTX, userID string) bool
IsConfigReadOnly() bool
IsFirstAdmin(user *model.User) bool
IsFirstUserAccount() bool
IsLeader() bool

View File

@ -12,12 +12,13 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/server/v8/channels/store/storetest/mocks"
"github.com/mattermost/mattermost-server/server/v8/model"
)
/* Temporarily comment out until MM-11108
/* TODO: Temporarily comment out until MM-11108
func TestAppRace(t *testing.T) {
for i := 0; i < 10; i++ {
a, err := New()
@ -61,6 +62,8 @@ func TestUnitUpdateConfig(t *testing.T) {
prev := *th.App.Config().ServiceSettings.SiteURL
require.False(t, th.App.IsConfigReadOnly())
var called int32
th.App.AddConfigListener(func(old, current *model.Config) {
atomic.AddInt32(&called, 1)

View File

@ -85,6 +85,12 @@ func TestSessionHasPermissionToChannel(t *testing.T) {
// Regression test for MM-29812
// Mock the channel store so getting the channel returns with an error, as per the bug report.
mockStore := mocks.Store{}
// Playbooks DB job requires a plugin mock
pluginStore := mocks.PluginStore{}
pluginStore.On("List", mock.Anything, mock.Anything, mock.Anything).Return([]string{}, nil)
mockStore.On("Plugin").Return(&pluginStore)
mockChannelStore := mocks.ChannelStore{}
mockChannelStore.On("Get", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("arbitrary error"))
mockChannelStore.On("GetAllChannelMembersForUser", mock.Anything, mock.Anything, mock.Anything).Return(th.App.Srv().Store().Channel().GetAllChannelMembersForUser(th.BasicUser.Id, false, false))

View File

@ -278,7 +278,7 @@ func TestGetBot(t *testing.T) {
}
func TestGetBots(t *testing.T) {
th := Setup(t)
th := Setup(t).DeleteBots()
defer th.TearDown()
OwnerId1 := model.NewId()

View File

@ -554,7 +554,7 @@ func TestGetDirectChannelCreatesChannelMemberHistoryRecord(t *testing.T) {
}
func TestAddUserToChannelCreatesChannelMemberHistoryRecord(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t).InitBasic().DeleteBots()
defer th.TearDown()
// create a user and add it to a channel

View File

@ -40,6 +40,10 @@ func (a *App) UpdateConfig(f func(*model.Config)) {
a.Srv().platform.UpdateConfig(f)
}
func (a *App) IsConfigReadOnly() bool {
return a.Srv().platform.IsConfigReadOnly()
}
func (a *App) ReloadConfig() error {
return a.Srv().platform.ReloadConfig()
}

View File

@ -52,8 +52,8 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
}
configStore := config.NewTestMemoryStore()
memoryConfig := configStore.Get()
memoryConfig.SqlSettings = *mainHelper.GetSQLSettings()
*memoryConfig.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins")
*memoryConfig.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp")
*memoryConfig.PluginSettings.AutomaticPrepackagedPlugins = false
@ -138,7 +138,7 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
return th
}
func Setup(tb testing.TB) *TestHelper {
func Setup(tb testing.TB, options ...Option) *TestHelper {
if testing.Short() {
tb.SkipNow()
}
@ -147,7 +147,7 @@ func Setup(tb testing.TB) *TestHelper {
dbStore.MarkSystemRanUnitTests()
mainHelper.PreloadMigrations()
return setupTestHelper(dbStore, false, true, nil, tb)
return setupTestHelper(dbStore, false, true, options, tb)
}
func SetupWithoutPreloadMigrations(tb testing.TB) *TestHelper {
@ -157,13 +157,16 @@ func SetupWithoutPreloadMigrations(tb testing.TB) *TestHelper {
dbStore := mainHelper.GetStore()
dbStore.DropAllTables()
dbStore.MarkSystemRanUnitTests()
// Only boards migrations are applied
mainHelper.PreloadBoardsMigrationsIfNeeded()
return setupTestHelper(dbStore, false, true, nil, tb)
}
func SetupWithStoreMock(tb testing.TB) *TestHelper {
mockStore := testlib.GetMockStoreForSetupFunctions()
th := setupTestHelper(mockStore, false, false, nil, tb)
setupOptions := []Option{SkipProductsInitialization()}
th := setupTestHelper(mockStore, false, false, setupOptions, tb)
statusMock := mocks.StatusStore{}
statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil)
statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil)
@ -184,7 +187,8 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper {
func SetupEnterpriseWithStoreMock(tb testing.TB) *TestHelper {
mockStore := testlib.GetMockStoreForSetupFunctions()
th := setupTestHelper(mockStore, true, false, nil, tb)
setupOptions := []Option{SkipProductsInitialization()}
th := setupTestHelper(mockStore, true, false, setupOptions, tb)
statusMock := mocks.StatusStore{}
statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil)
statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil)
@ -249,6 +253,14 @@ func (th *TestHelper) InitBasic() *TestHelper {
return th
}
func (th *TestHelper) DeleteBots() *TestHelper {
preexistingBots, _ := th.App.GetBots(&model.BotGetOptions{Page: 0, PerPage: 100})
for _, bot := range preexistingBots {
th.App.PermanentDeleteBot(bot.UserId)
}
return th
}
func (*TestHelper) MakeEmail() string {
return "success_" + model.NewId() + "@simulator.amazonses.com"
}

View File

@ -1433,6 +1433,10 @@ func TestPushNotificationRace(t *testing.T) {
memoryStore := config.NewTestMemoryStore()
mockStore := testlib.GetMockStoreForSetupFunctions()
// Playbooks DB job requires a plugin mock
pluginStore := mocks.PluginStore{}
pluginStore.On("List", mock.Anything, mock.Anything, mock.Anything).Return([]string{}, nil)
mockStore.On("Plugin").Return(&pluginStore)
mockPreferenceStore := mocks.PreferenceStore{}
mockPreferenceStore.On("Get",
mock.AnythingOfType("string"),
@ -1445,10 +1449,12 @@ func TestPushNotificationRace(t *testing.T) {
Router: mux.NewRouter(),
}
var err error
s.platform, err = platform.New(platform.ServiceConfig{
ConfigStore: memoryStore,
}, platform.SetFileStore(&fmocks.FileBackend{}))
s.SetStore(mockStore)
s.platform, err = platform.New(
platform.ServiceConfig{
ConfigStore: memoryStore,
},
platform.SetFileStore(&fmocks.FileBackend{}),
platform.StoreOverride(mockStore))
require.NoError(t, err)
serviceMap := map[product.ServiceKey]any{
ServerKey: s,

View File

@ -12009,6 +12009,23 @@ func (a *OpenTracingAppLayer) IsCRTEnabledForUser(c request.CTX, userID string)
return resultVar0
}
func (a *OpenTracingAppLayer) IsConfigReadOnly() bool {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.IsConfigReadOnly")
a.ctx = newCtx
a.app.Srv().Store().SetContext(newCtx)
defer func() {
a.app.Srv().Store().SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.IsConfigReadOnly()
return resultVar0
}
func (a *OpenTracingAppLayer) IsFirstAdmin(user *model.User) bool {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.IsFirstAdmin")

View File

@ -103,6 +103,17 @@ func SkipPostInitialization() Option {
}
}
// SkipProductsInitialization is intended for testing only, in cases
// where we're mocking components like the store and products cannot
// be initialized correctly
func SkipProductsInitialization() Option {
return func(s *Server) error {
s.skipProductsInit = true
return nil
}
}
type AppOption func(a *App)
type AppOptionCreator func() []AppOption

View File

@ -65,6 +65,11 @@ func (ps *PlatformService) UpdateConfig(f func(*model.Config)) {
}
}
// IsConfigReadOnly returns true if the underlying configstore is readonly.
func (ps *PlatformService) IsConfigReadOnly() bool {
return ps.configStore.IsReadOnly()
}
// SaveConfig replaces the active configuration, optionally notifying cluster peers.
// It returns both the previous and current configs.
func (ps *PlatformService) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) {

View File

@ -99,6 +99,7 @@ func (th *TestHelper) InitBasic() *TestHelper {
func SetupWithStoreMock(tb testing.TB, options ...Option) *TestHelper {
mockStore := testlib.GetMockStoreForSetupFunctions()
options = append(options, StoreOverride(mockStore))
th := setupTestHelper(mockStore, false, false, tb, options...)
statusMock := mocks.StatusStore{}
statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil)
@ -136,6 +137,7 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
configStore := config.NewTestMemoryStore()
memoryConfig := configStore.Get()
memoryConfig.SqlSettings = *mainHelper.GetSQLSettings()
*memoryConfig.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins")
*memoryConfig.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp")
*memoryConfig.PluginSettings.AutomaticPrepackagedPlugins = false

View File

@ -28,16 +28,7 @@ func TestReadReplicaDisabledBasedOnLicense(t *testing.T) {
if driverName == "" {
driverName = model.DatabaseDriverPostgres
}
dsn := ""
if driverName == model.DatabaseDriverPostgres {
dsn = os.Getenv("TEST_DATABASE_POSTGRESQL_DSN")
} else {
dsn = os.Getenv("TEST_DATABASE_MYSQL_DSN")
}
cfg.SqlSettings = *storetest.MakeSqlSettings(driverName, false)
if dsn != "" {
cfg.SqlSettings.DataSource = &dsn
}
cfg.SqlSettings.DataSourceReplicas = []string{*cfg.SqlSettings.DataSource}
cfg.SqlSettings.DataSourceSearchReplicas = []string{*cfg.SqlSettings.DataSource}

View File

@ -82,6 +82,7 @@ func TestHubStopWithMultipleConnections(t *testing.T) {
// block the caller indefinitely.
func TestHubStopRaceCondition(t *testing.T) {
th := Setup(t).InitBasic()
defer th.Service.Store.Close()
// We do not call TearDown because th.TearDown shuts down the hub again. And hub close is not idempotent.
// Making it idempotent is not really important to the server because close only happens once.
// So we just use this quick hack for the test.

View File

@ -304,7 +304,7 @@ func TestPluginAPIUpdateUserPreferences(t *testing.T) {
}
func TestPluginAPIGetUsers(t *testing.T) {
th := Setup(t)
th := Setup(t).DeleteBots()
defer th.TearDown()
api := th.SetupPluginAPI()
@ -1171,7 +1171,7 @@ func TestBasicAPIPlugins(t *testing.T) {
mainPath := path.Join(testFolder, d, "main.go")
_, err := os.Stat(mainPath)
require.NoError(t, err, "Cannot find plugin main file at %v", mainPath)
th := Setup(t).InitBasic()
th := Setup(t).InitBasic().DeleteBots()
defer th.TearDown()
setDefaultPluginConfig(th, dir.Name())
err = pluginAPIHookTest(t, th, mainPath, dir.Name(), defaultSchema)

View File

@ -465,7 +465,6 @@ func (p *TProduct) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*
}
func TestProductCommands(t *testing.T) {
products := map[string]product.Manifest{
"productT": {
Initializer: newTProduct,
@ -474,10 +473,11 @@ func TestProductCommands(t *testing.T) {
}
t.Run("Execute product command", func(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t, SkipProductsInitialization()).InitBasic()
defer th.TearDown()
// Server hijack.
// This must be done in a cleaner way.
th.Server.skipProductsInit = false
th.Server.initializeProducts(products, th.Server.services)
th.Server.products["productT"].Start()
require.Len(t, th.Server.products, 2) // 1 product + channels
@ -504,11 +504,11 @@ func TestProductCommands(t *testing.T) {
})
t.Run("Product commands can override builtin commands", func(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t, SkipProductsInitialization()).InitBasic()
defer th.TearDown()
// Server hijack.
// This must be done in a cleaner way.
th.Server.skipProductsInit = false
th.Server.initializeProducts(products, th.Server.services)
th.Server.products["productT"].Start()
require.Len(t, th.Server.products, 2) // 1 product + channels
@ -535,8 +535,7 @@ func TestProductCommands(t *testing.T) {
})
t.Run("Plugin commands can override product commands", func(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t, SkipProductsInitialization()).InitBasic()
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {
@ -602,6 +601,7 @@ func TestProductCommands(t *testing.T) {
// Server hijack.
// This must be done in a cleaner way.
th.Server.skipProductsInit = false
th.Server.initializeProducts(products, th.Server.services)
th.Server.products["productT"].Start()
require.Len(t, th.Server.products, 2) // 1 product + channels

View File

@ -1202,7 +1202,7 @@ func TestHookReactionHasBeenRemoved(t *testing.T) {
}
func TestHookRunDataRetention(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t, SkipProductsInitialization()).InitBasic()
defer th.TearDown()
tearDown, pluginIDs, _ := SetAppEnvironmentWithPlugins(t,

View File

@ -3150,6 +3150,7 @@ func TestGetTopThreadsForUserSince(t *testing.T) {
}
func TestGetEditHistoryForPost(t *testing.T) {
t.Skip("This needs fixing, OriginalId seems to be empty for all posts")
th := Setup(t).InitBasic()
defer th.TearDown()

View File

@ -10,6 +10,7 @@ import (
"strings"
"github.com/mattermost/mattermost-server/server/v8/channels/product"
"github.com/mattermost/mattermost-server/server/v8/platform/shared/mlog"
)
func (s *Server) initializeProducts(
@ -71,6 +72,11 @@ func (s *Server) initializeProducts(
}
func (s *Server) shouldStart(product string) bool {
if s.skipProductsInit && product != "channels" {
s.Log().Warn("Skipping product start: disabled via server options", mlog.String("product", product))
return false
}
if product == "boards" {
if os.Getenv("MM_DISABLE_BOARDS") == "true" {
s.Log().Warn("Skipping Boards start: disabled via env var")

View File

@ -39,8 +39,14 @@ func (p *productB) Start() error { return nil }
func (p *productB) Stop() error { return nil }
func TestInitializeProducts(t *testing.T) {
ps, err := platform.New(platform.ServiceConfig{ConfigStore: config.NewTestMemoryStore()})
configStore := config.NewTestMemoryStore()
memoryConfig := configStore.Get()
memoryConfig.SqlSettings = *mainHelper.GetSQLSettings()
configStore.Set(memoryConfig)
ps, err := platform.New(platform.ServiceConfig{ConfigStore: configStore})
require.NoError(t, err)
defer ps.Shutdown()
t.Run("2 products and no circular dependency", func(t *testing.T) {
serviceMap := map[product.ServiceKey]any{
@ -148,24 +154,4 @@ func TestInitializeProducts(t *testing.T) {
require.NoError(t, err)
require.Len(t, server.products, 2)
})
t.Run("boards product to be blocked", func(t *testing.T) {
products := map[string]product.Manifest{
"productA": {
Initializer: newProductA,
},
"boards": {
Initializer: newProductB,
},
}
server := &Server{
products: make(map[string]product.Product),
platform: ps,
}
err := server.initializeProducts(products, map[product.ServiceKey]any{})
require.NoError(t, err)
require.Len(t, server.products, 1)
})
}

View File

@ -137,6 +137,8 @@ type Server struct {
tracer *tracing.Tracer
skipProductsInit bool
products map[string]product.Product
services map[product.ServiceKey]any

View File

@ -32,12 +32,17 @@ import (
"github.com/mattermost/mattermost-server/server/v8/platform/shared/mlog"
)
func newServer(t *testing.T) (*Server, error) {
return newServerWithConfig(t, func(_ *model.Config) {})
}
func newServerWithConfig(t *testing.T, f func(cfg *model.Config)) (*Server, error) {
configStore, err := config.NewMemoryStore()
require.NoError(t, err)
store, err := config.NewStoreFromBacking(configStore, nil, false)
require.NoError(t, err)
cfg := store.Get()
cfg.SqlSettings = *mainHelper.GetSQLSettings()
f(cfg)
store.Set(cfg)
@ -61,13 +66,13 @@ func TestStartServerSuccess(t *testing.T) {
}
func TestStartServerPortUnavailable(t *testing.T) {
s, err := NewServer()
require.NoError(t, err)
// Listen on the next available port
listener, err := net.Listen("tcp", "localhost:0")
require.NoError(t, err)
s, err := newServer(t)
require.NoError(t, err)
// Attempt to listen on the port used above.
s.platform.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.ListenAddress = listener.Addr().String()
@ -105,6 +110,7 @@ func TestStartServerNoS3Bucket(t *testing.T) {
AmazonS3SSL: model.NewBool(false),
}
*cfg.ServiceSettings.ListenAddress = "localhost:0"
cfg.SqlSettings = *mainHelper.GetSQLSettings()
_, _, err := store.Set(cfg)
require.NoError(t, err)
@ -162,7 +168,7 @@ func TestDatabaseTypeAndMattermostVersion(t *testing.T) {
os.Setenv("MM_SQLSETTINGS_DRIVERNAME", "postgres")
th := Setup(t)
th := Setup(t, SkipProductsInitialization())
defer th.TearDown()
databaseType, mattermostVersion := th.Server.DatabaseTypeAndSchemaVersion()
@ -171,7 +177,7 @@ func TestDatabaseTypeAndMattermostVersion(t *testing.T) {
os.Setenv("MM_SQLSETTINGS_DRIVERNAME", "mysql")
th2 := Setup(t)
th2 := Setup(t, SkipProductsInitialization())
defer th2.TearDown()
databaseType, mattermostVersion = th2.Server.DatabaseTypeAndSchemaVersion()
@ -190,6 +196,7 @@ func TestStartServerTLSVersion(t *testing.T) {
*cfg.ServiceSettings.TLSMinVer = "1.2"
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
cfg.SqlSettings = *mainHelper.GetSQLSettings()
store.Set(cfg)
@ -316,7 +323,7 @@ func TestPanicLog(t *testing.T) {
logger.LockConfiguration()
// Creating a server with logger
s, err := NewServer()
s, err := newServer(t)
require.NoError(t, err)
s.Platform().SetLogger(logger)

View File

@ -51,6 +51,7 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
if configSet != nil {
configSet(memoryConfig)
}
memoryConfig.SqlSettings = *mainHelper.GetSQLSettings()
*memoryConfig.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins")
*memoryConfig.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp")
*memoryConfig.PluginSettings.AutomaticPrepackagedPlugins = false
@ -142,6 +143,7 @@ func setup(tb testing.TB) *TestHelper {
dbStore := mainHelper.GetStore()
dbStore.DropAllTables()
dbStore.MarkSystemRanUnitTests()
mainHelper.PreloadBoardsMigrationsIfNeeded()
return setupTestHelper(dbStore, false, true, tb, nil)
}

View File

@ -1026,7 +1026,7 @@ func TestCreateUserWithToken(t *testing.T) {
}
func TestPermanentDeleteUser(t *testing.T) {
th := Setup(t).InitBasic()
th := Setup(t).InitBasic().DeleteBots()
defer th.TearDown()
b := []byte("testimage")

View File

@ -14,7 +14,7 @@ import (
)
func TestRestrictedViewMembers(t *testing.T) {
th := Setup(t)
th := Setup(t).DeleteBots()
defer th.TearDown()
user1 := th.CreateUser()

View File

@ -993,6 +993,7 @@ func (ss *SqlStore) TrueUpReview() store.TrueUpReviewStore {
}
func (ss *SqlStore) DropAllTables() {
var tableSchemaFn string
if ss.DriverName() == model.DatabaseDriverPostgres {
ss.masterX.Exec(`DO
$func$
@ -1002,18 +1003,57 @@ func (ss *SqlStore) DropAllTables() {
FROM pg_class
WHERE relkind = 'r' -- only tables
AND relnamespace = 'public'::regnamespace
AND NOT relname = 'db_migrations'
AND NOT (
relname = 'db_migrations' OR
relname = 'focalboard_schema_migrations' OR
relname = 'focalboard_boards' OR
relname = 'focalboard_blocks'
)
);
END
$func$;`)
tableSchemaFn = "current_schema()"
} else {
tables := []string{}
ss.masterX.Select(&tables, `show tables`)
for _, t := range tables {
if t != "db_migrations" {
if t != "db_migrations" &&
t != "focalboard_schema_migrations" &&
t != "focalboard_boards" &&
t != "focalboard_blocks" {
ss.masterX.Exec(`TRUNCATE TABLE ` + t)
}
}
tableSchemaFn = "DATABASE()"
}
var boardsTableCount int
err := ss.masterX.Get(&boardsTableCount, `
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = `+tableSchemaFn+`
AND TABLE_NAME = 'focalboard_schema_migrations'`)
if err != nil {
panic(errors.Wrap(err, "Error dropping all tables. Cannot query INFORMATION_SCHEMA table to check for focalboard_schema_migrations table"))
}
if boardsTableCount != 0 {
_, blErr := ss.masterX.Exec(`
DELETE FROM focalboard_blocks
WHERE board_id IN (
SELECT id
FROM focalboard_boards
WHERE NOT is_template
)`)
if blErr != nil {
panic(errors.Wrap(blErr, "Error deleting all non-template blocks"))
}
_, boErr := ss.masterX.Exec(`DELETE FROM focalboard_boards WHERE NOT is_template`)
if boErr != nil {
panic(errors.Wrap(boErr, "Error delegint all non-template boards"))
}
}
}

View File

@ -41,6 +41,11 @@ type HelperOptions struct {
}
func NewMainHelper() *MainHelper {
// Ignore any globally defined datasource if a test dsn defined
if os.Getenv("TEST_DATABASE_MYSQL_DSN") != "" || os.Getenv("TEST_DATABASE_POSTGRESQL_DSN") != "" {
os.Unsetenv("MM_SQLSETTINGS_DATASOURCE")
}
return NewMainHelperWithOptions(&HelperOptions{
EnableStore: true,
EnableResources: true,
@ -48,6 +53,11 @@ func NewMainHelper() *MainHelper {
}
func NewMainHelperWithOptions(options *HelperOptions) *MainHelper {
// Ignore any globally defined datasource if a test dsn defined
if os.Getenv("TEST_DATABASE_MYSQL_DSN") != "" || os.Getenv("TEST_DATABASE_POSTGRESQL_DSN") != "" {
os.Unsetenv("MM_SQLSETTINGS_DATASOURCE")
}
var mainHelper MainHelper
flag.Parse()
@ -153,6 +163,7 @@ func (h *MainHelper) setupResources() {
func (h *MainHelper) PreloadMigrations() {
var buf []byte
var err error
basePath := os.Getenv("MM_SERVER_PATH")
if basePath == "" {
basePath = "mattermost-server/server"
@ -177,6 +188,62 @@ func (h *MainHelper) PreloadMigrations() {
if err != nil {
panic(errors.Wrap(err, "Error preloading migrations. Check if you have &multiStatements=true in your DSN if you are using MySQL. Or perhaps the schema changed? If yes, then update the warmup files accordingly"))
}
h.PreloadBoardsMigrationsIfNeeded()
}
// PreloadBoardsMigrationsIfNeeded loads boards migrations if the
// focalboard_schema_migrations table exists already.
// Besides this, the same compatibility and breaking conditions that
// PreloadMigrations has apply here.
//
// Re-generate the files with:
// pg_dump -a -h localhost -U mmuser -d <> --no-comments --inserts -t focalboard_system_settings
// mysqldump -u root -p <> --no-create-info --extended-insert=FALSE focalboard_system_settings
func (h *MainHelper) PreloadBoardsMigrationsIfNeeded() {
tableSchemaFn := "current_schema()"
if *h.Settings.DriverName == model.DatabaseDriverMysql {
tableSchemaFn = "DATABASE()"
}
basePath := os.Getenv("MM_SERVER_PATH")
if basePath == "" {
basePath = "mattermost-server/server"
}
relPath := "channels/testlib/testdata"
handle := h.SQLStore.GetMasterX()
var boardsTableCount int
gErr := handle.Get(&boardsTableCount, `
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = `+tableSchemaFn+`
AND TABLE_NAME = 'focalboard_schema_migrations'`)
if gErr != nil {
panic(errors.Wrap(gErr, "Error preloading migrations. Cannot query INFORMATION_SCHEMA table to check for focalboard_schema_migrations table"))
}
var buf []byte
var err error
if boardsTableCount != 0 {
switch *h.Settings.DriverName {
case model.DatabaseDriverPostgres:
boardsFinalPath := filepath.Join(basePath, relPath, "boards_postgres_migration_warmup.sql")
buf, err = os.ReadFile(boardsFinalPath)
if err != nil {
panic(fmt.Errorf("cannot read file: %v", err))
}
case model.DatabaseDriverMysql:
boardsFinalPath := filepath.Join(basePath, relPath, "boards_mysql_migration_warmup.sql")
buf, err = os.ReadFile(boardsFinalPath)
if err != nil {
panic(fmt.Errorf("cannot read file: %v", err))
}
}
if _, err := handle.Exec(string(buf)); err != nil {
panic(errors.Wrap(err, "Error preloading boards migrations. Check if you have &multiStatements=true in your DSN if you are using MySQL. Or perhaps the schema changed? If yes, then update the warmup files accordingly"))
}
}
}
func (h *MainHelper) Close() error {

View File

@ -101,6 +101,9 @@ func GetMockStoreForSetupFunctions() *mocks.Store {
oAuthStore := mocks.OAuthStore{}
groupStore := mocks.GroupStore{}
pluginStore := mocks.PluginStore{}
pluginStore.On("List", mock.Anything, mock.Anything, mock.Anything).Return([]string{}, nil)
mockStore.On("System").Return(&systemStore)
mockStore.On("User").Return(&userStore)
mockStore.On("Post").Return(&postStore)
@ -116,6 +119,7 @@ func GetMockStoreForSetupFunctions() *mocks.Store {
mockStore.On("OAuth").Return(&oAuthStore)
mockStore.On("Group").Return(&groupStore)
mockStore.On("GetDBSchemaVersion").Return(1, nil)
mockStore.On("Plugin").Return(&pluginStore)
return &mockStore
}

View File

@ -0,0 +1,41 @@
-- MySQL dump 10.13 Distrib 5.7.12, for Linux (x86_64)
--
-- Host: localhost Database: mattermost_test
-- ------------------------------------------------------
-- Server version 5.7.12
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `focalboard_system_settings`
--
LOCK TABLES `focalboard_system_settings` WRITE;
/*!40000 ALTER TABLE `focalboard_system_settings` DISABLE KEYS */;
INSERT INTO `focalboard_system_settings` VALUES ('CategoryUuidIdMigrationComplete','true');
INSERT INTO `focalboard_system_settings` VALUES ('DeDuplicateCategoryBoardTableComplete','true');
INSERT INTO `focalboard_system_settings` VALUES ('DeletedMembershipBoardsMigrationComplete','true');
INSERT INTO `focalboard_system_settings` VALUES ('TeamLessBoardsMigrationComplete','true');
INSERT INTO `focalboard_system_settings` VALUES ('UniqueIDsMigrationComplete','true');
/*!40000 ALTER TABLE `focalboard_system_settings` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-03-31 11:37:35

View File

@ -0,0 +1,26 @@
--
-- PostgreSQL database dump
--
-- Dumped from database version 10.20 (Debian 10.20-1.pgdg90+1)
-- Dumped by pg_dump version 14.7
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
--
-- Data for Name: focalboard_system_settings; Type: TABLE DATA; Schema: public; Owner: mmuser
--
INSERT INTO public.focalboard_system_settings VALUES ('UniqueIDsMigrationComplete', 'true');
INSERT INTO public.focalboard_system_settings VALUES ('TeamLessBoardsMigrationComplete', 'true');
INSERT INTO public.focalboard_system_settings VALUES ('DeletedMembershipBoardsMigrationComplete', 'true');
INSERT INTO public.focalboard_system_settings VALUES ('CategoryUuidIdMigrationComplete', 'true');
INSERT INTO public.focalboard_system_settings VALUES ('DeDuplicateCategoryBoardTableComplete', 'true');
--
-- PostgreSQL database dump complete
--

View File

@ -55,7 +55,7 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper {
tb.SkipNow()
}
th := setupTestHelper(tb, false)
th := setupTestHelper(tb, false, []app.Option{app.SkipProductsInitialization()})
emptyMockStore := mocks.Store{}
emptyMockStore.On("Close").Return(nil)
th.App.Srv().SetStore(&emptyMockStore)
@ -68,17 +68,18 @@ func Setup(tb testing.TB) *TestHelper {
}
store := mainHelper.GetStore()
store.DropAllTables()
return setupTestHelper(tb, true)
mainHelper.PreloadBoardsMigrationsIfNeeded()
return setupTestHelper(tb, true, nil)
}
func setupTestHelper(tb testing.TB, includeCacheLayer bool) *TestHelper {
func setupTestHelper(tb testing.TB, includeCacheLayer bool, options []app.Option) *TestHelper {
memoryStore := config.NewTestMemoryStore()
newConfig := memoryStore.Get().Clone()
newConfig.SqlSettings = *mainHelper.GetSQLSettings()
*newConfig.AnnouncementSettings.AdminNoticesEnabled = false
*newConfig.AnnouncementSettings.UserNoticesEnabled = false
*newConfig.PluginSettings.AutomaticPrepackagedPlugins = false
memoryStore.Set(newConfig)
var options []app.Option
options = append(options, app.ConfigStore(memoryStore))
options = append(options, app.StoreOverride(mainHelper.Store))

View File

@ -65,6 +65,7 @@ func TestRunServerSuccess(t *testing.T) {
// Use non-default listening port in case another server instance is already running.
cfg := configStore.Get()
*cfg.ServiceSettings.ListenAddress = unitTestListeningPort
cfg.SqlSettings = *mainHelper.GetSQLSettings()
configStore.Set(cfg)
err := runServer(configStore, th.interruptChan)
@ -117,6 +118,7 @@ func TestRunServerSystemdNotification(t *testing.T) {
// Use non-default listening port in case another server instance is already running.
cfg := configStore.Get()
*cfg.ServiceSettings.ListenAddress = unitTestListeningPort
cfg.SqlSettings = *mainHelper.GetSQLSettings()
configStore.Set(cfg)
// Start and stop the server
@ -142,6 +144,7 @@ func TestRunServerNoSystemd(t *testing.T) {
// Use non-default listening port in case another server instance is already running.
cfg := configStore.Get()
*cfg.ServiceSettings.ListenAddress = unitTestListeningPort
cfg.SqlSettings = *mainHelper.GetSQLSettings()
configStore.Set(cfg)
err := runServer(configStore, th.interruptChan)