* materialize PublicChannels table Introduce triggers for each supported database that automatically maintain a subset of the Channels table corresponding to only public channels. This improves corresponding queries that no longer need to filter out 99% DM channels. This initial commit modifies the channel store directly for easier code reviewing, but the next wraps an experimental version around it to enable a kill switch in case there are unforeseen performance regressions. This addresses [MM-11886](https://mattermost.atlassian.net/browse/MM-11886) and [MM-11945](https://mattermost.atlassian.net/browse/MM-11945). * extract the experimental public channels materialization Wrap the original channel store with an experimental version that leverages the materialized public channels, but can be disabled to fallback to the original implementation. This addresses MM-11947. * s/ExperimentalPublicChannelsMaterialization/EnablePublicChannelsMaterialization/ * simplify error handling * move experimental config listener until after store is initialized
138 строки
2.8 KiB
Go
138 строки
2.8 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
package sqlstore
|
|
|
|
import (
|
|
"os"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/mattermost/mattermost-server/mlog"
|
|
"github.com/mattermost/mattermost-server/model"
|
|
"github.com/mattermost/mattermost-server/store"
|
|
"github.com/mattermost/mattermost-server/store/storetest"
|
|
"github.com/mattermost/mattermost-server/utils"
|
|
)
|
|
|
|
var storeTypes = []*struct {
|
|
Name string
|
|
Func func() (*storetest.RunningContainer, *model.SqlSettings, error)
|
|
Container *storetest.RunningContainer
|
|
SqlSupplier *SqlSupplier
|
|
Store store.Store
|
|
}{
|
|
{
|
|
Name: "MySQL",
|
|
Func: storetest.NewMySQLContainer,
|
|
},
|
|
{
|
|
Name: "PostgreSQL",
|
|
Func: storetest.NewPostgreSQLContainer,
|
|
},
|
|
}
|
|
|
|
func StoreTest(t *testing.T, f func(*testing.T, store.Store)) {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
tearDownStores()
|
|
panic(err)
|
|
}
|
|
}()
|
|
for _, st := range storeTypes {
|
|
st := st
|
|
t.Run(st.Name, func(t *testing.T) { f(t, st.Store) })
|
|
}
|
|
}
|
|
|
|
func StoreTestWithSqlSupplier(t *testing.T, f func(*testing.T, store.Store, storetest.SqlSupplier)) {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
tearDownStores()
|
|
panic(err)
|
|
}
|
|
}()
|
|
for _, st := range storeTypes {
|
|
st := st
|
|
t.Run(st.Name, func(t *testing.T) { f(t, st.Store, st.SqlSupplier) })
|
|
}
|
|
}
|
|
|
|
func initStores() {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
tearDownStores()
|
|
panic(err)
|
|
}
|
|
}()
|
|
var wg sync.WaitGroup
|
|
errCh := make(chan error, len(storeTypes))
|
|
wg.Add(len(storeTypes))
|
|
for _, st := range storeTypes {
|
|
st := st
|
|
go func() {
|
|
defer wg.Done()
|
|
container, settings, err := st.Func()
|
|
if err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
st.Container = container
|
|
st.SqlSupplier = NewSqlSupplier(*settings, nil)
|
|
st.Store = store.NewLayeredStore(st.SqlSupplier, nil, nil)
|
|
st.Store.MarkSystemRanUnitTests()
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
select {
|
|
case err := <-errCh:
|
|
panic(err)
|
|
default:
|
|
}
|
|
}
|
|
|
|
var tearDownStoresOnce sync.Once
|
|
|
|
func tearDownStores() {
|
|
tearDownStoresOnce.Do(func() {
|
|
var wg sync.WaitGroup
|
|
wg.Add(len(storeTypes))
|
|
for _, st := range storeTypes {
|
|
st := st
|
|
go func() {
|
|
if st.Store != nil {
|
|
st.Store.Close()
|
|
}
|
|
if st.Container != nil {
|
|
st.Container.Stop()
|
|
}
|
|
wg.Done()
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
})
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
// Setup a global logger to catch tests logging outside of app context
|
|
// The global logger will be stomped by apps initalizing but that's fine for testing. Ideally this won't happen.
|
|
mlog.InitGlobalLogger(mlog.NewLogger(&mlog.LoggerConfiguration{
|
|
EnableConsole: true,
|
|
ConsoleJson: true,
|
|
ConsoleLevel: "error",
|
|
EnableFile: false,
|
|
}))
|
|
|
|
utils.TranslationsPreInit()
|
|
|
|
status := 0
|
|
|
|
initStores()
|
|
defer func() {
|
|
tearDownStores()
|
|
os.Exit(status)
|
|
}()
|
|
|
|
status = m.Run()
|
|
}
|