github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/app/apptestlib.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "encoding/json" 8 "io" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "time" 13 14 "github.com/mattermost/mattermost-server/einterfaces" 15 "github.com/mattermost/mattermost-server/mlog" 16 "github.com/mattermost/mattermost-server/model" 17 "github.com/mattermost/mattermost-server/plugin" 18 "github.com/mattermost/mattermost-server/plugin/pluginenv" 19 "github.com/mattermost/mattermost-server/store" 20 "github.com/mattermost/mattermost-server/store/sqlstore" 21 "github.com/mattermost/mattermost-server/store/storetest" 22 "github.com/mattermost/mattermost-server/utils" 23 ) 24 25 type TestHelper struct { 26 App *App 27 BasicTeam *model.Team 28 BasicUser *model.User 29 BasicUser2 *model.User 30 BasicChannel *model.Channel 31 BasicPost *model.Post 32 33 SystemAdminUser *model.User 34 35 tempConfigPath string 36 tempWorkspace string 37 pluginHooks map[string]plugin.Hooks 38 } 39 40 type persistentTestStore struct { 41 store.Store 42 } 43 44 func (*persistentTestStore) Close() {} 45 46 var testStoreContainer *storetest.RunningContainer 47 var testStore *persistentTestStore 48 var testStoreSqlSupplier *sqlstore.SqlSupplier 49 var testClusterInterface *FakeClusterInterface 50 51 // UseTestStore sets the container and corresponding settings to use for tests. Once the tests are 52 // complete (e.g. at the end of your TestMain implementation), you should call StopTestStore. 53 func UseTestStore(container *storetest.RunningContainer, settings *model.SqlSettings) { 54 testClusterInterface = &FakeClusterInterface{} 55 testStoreContainer = container 56 testStoreSqlSupplier = sqlstore.NewSqlSupplier(*settings, nil) 57 testStore = &persistentTestStore{store.NewLayeredStore(testStoreSqlSupplier, nil, testClusterInterface)} 58 } 59 60 func StopTestStore() { 61 if testStoreContainer != nil { 62 testStoreContainer.Stop() 63 testStoreContainer = nil 64 } 65 } 66 67 func setupTestHelper(enterprise bool) *TestHelper { 68 permConfig, err := os.Open(utils.FindConfigFile("config.json")) 69 if err != nil { 70 panic(err) 71 } 72 defer permConfig.Close() 73 tempConfig, err := ioutil.TempFile("", "") 74 if err != nil { 75 panic(err) 76 } 77 _, err = io.Copy(tempConfig, permConfig) 78 tempConfig.Close() 79 if err != nil { 80 panic(err) 81 } 82 83 options := []Option{ConfigFile(tempConfig.Name()), DisableConfigWatch} 84 if testStore != nil { 85 options = append(options, StoreOverride(testStore)) 86 } 87 88 a, err := New(options...) 89 if err != nil { 90 panic(err) 91 } 92 93 th := &TestHelper{ 94 App: a, 95 pluginHooks: make(map[string]plugin.Hooks), 96 tempConfigPath: tempConfig.Name(), 97 } 98 99 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 }) 100 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false }) 101 prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress 102 if testStore != nil { 103 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) 104 } 105 serverErr := th.App.StartServer() 106 if serverErr != nil { 107 panic(serverErr) 108 } 109 110 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) 111 112 th.App.DoAdvancedPermissionsMigration() 113 114 th.App.Srv.Store.MarkSystemRanUnitTests() 115 116 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) 117 118 if enterprise { 119 th.App.SetLicense(model.NewTestLicense()) 120 } else { 121 th.App.SetLicense(nil) 122 } 123 124 return th 125 } 126 127 func SetupEnterprise() *TestHelper { 128 return setupTestHelper(true) 129 } 130 131 func Setup() *TestHelper { 132 return setupTestHelper(false) 133 } 134 135 func (me *TestHelper) InitBasic() *TestHelper { 136 me.BasicTeam = me.CreateTeam() 137 me.BasicUser = me.CreateUser() 138 me.LinkUserToTeam(me.BasicUser, me.BasicTeam) 139 me.BasicUser2 = me.CreateUser() 140 me.LinkUserToTeam(me.BasicUser2, me.BasicTeam) 141 me.BasicChannel = me.CreateChannel(me.BasicTeam) 142 me.BasicPost = me.CreatePost(me.BasicChannel) 143 144 return me 145 } 146 147 func (me *TestHelper) InitSystemAdmin() *TestHelper { 148 me.SystemAdminUser = me.CreateUser() 149 me.App.UpdateUserRoles(me.SystemAdminUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false) 150 me.SystemAdminUser, _ = me.App.GetUser(me.SystemAdminUser.Id) 151 152 return me 153 } 154 155 func (me *TestHelper) MakeEmail() string { 156 return "success_" + model.NewId() + "@simulator.amazonses.com" 157 } 158 159 func (me *TestHelper) CreateTeam() *model.Team { 160 id := model.NewId() 161 team := &model.Team{ 162 DisplayName: "dn_" + id, 163 Name: "name" + id, 164 Email: "success+" + id + "@simulator.amazonses.com", 165 Type: model.TEAM_OPEN, 166 } 167 168 utils.DisableDebugLogForTest() 169 var err *model.AppError 170 if team, err = me.App.CreateTeam(team); err != nil { 171 mlog.Error(err.Error()) 172 173 time.Sleep(time.Second) 174 panic(err) 175 } 176 utils.EnableDebugLogForTest() 177 return team 178 } 179 180 func (me *TestHelper) CreateUser() *model.User { 181 id := model.NewId() 182 183 user := &model.User{ 184 Email: "success+" + id + "@simulator.amazonses.com", 185 Username: "un_" + id, 186 Nickname: "nn_" + id, 187 Password: "Password1", 188 EmailVerified: true, 189 } 190 191 utils.DisableDebugLogForTest() 192 var err *model.AppError 193 if user, err = me.App.CreateUser(user); err != nil { 194 mlog.Error(err.Error()) 195 196 time.Sleep(time.Second) 197 panic(err) 198 } 199 utils.EnableDebugLogForTest() 200 return user 201 } 202 203 func (me *TestHelper) CreateChannel(team *model.Team) *model.Channel { 204 return me.createChannel(team, model.CHANNEL_OPEN) 205 } 206 207 func (me *TestHelper) createChannel(team *model.Team, channelType string) *model.Channel { 208 id := model.NewId() 209 210 channel := &model.Channel{ 211 DisplayName: "dn_" + id, 212 Name: "name_" + id, 213 Type: channelType, 214 TeamId: team.Id, 215 CreatorId: me.BasicUser.Id, 216 } 217 218 utils.DisableDebugLogForTest() 219 var err *model.AppError 220 if channel, err = me.App.CreateChannel(channel, true); err != nil { 221 mlog.Error(err.Error()) 222 223 time.Sleep(time.Second) 224 panic(err) 225 } 226 utils.EnableDebugLogForTest() 227 return channel 228 } 229 230 func (me *TestHelper) CreateDmChannel(user *model.User) *model.Channel { 231 utils.DisableDebugLogForTest() 232 var err *model.AppError 233 var channel *model.Channel 234 if channel, err = me.App.CreateDirectChannel(me.BasicUser.Id, user.Id); err != nil { 235 mlog.Error(err.Error()) 236 237 time.Sleep(time.Second) 238 panic(err) 239 } 240 utils.EnableDebugLogForTest() 241 return channel 242 } 243 244 func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post { 245 id := model.NewId() 246 247 post := &model.Post{ 248 UserId: me.BasicUser.Id, 249 ChannelId: channel.Id, 250 Message: "message_" + id, 251 CreateAt: model.GetMillis() - 10000, 252 } 253 254 utils.DisableDebugLogForTest() 255 var err *model.AppError 256 if post, err = me.App.CreatePost(post, channel, false); err != nil { 257 mlog.Error(err.Error()) 258 259 time.Sleep(time.Second) 260 panic(err) 261 } 262 utils.EnableDebugLogForTest() 263 return post 264 } 265 266 func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) { 267 utils.DisableDebugLogForTest() 268 269 err := me.App.JoinUserToTeam(team, user, "") 270 if err != nil { 271 mlog.Error(err.Error()) 272 273 time.Sleep(time.Second) 274 panic(err) 275 } 276 277 utils.EnableDebugLogForTest() 278 } 279 280 func (me *TestHelper) AddUserToChannel(user *model.User, channel *model.Channel) *model.ChannelMember { 281 utils.DisableDebugLogForTest() 282 283 member, err := me.App.AddUserToChannel(user, channel) 284 if err != nil { 285 mlog.Error(err.Error()) 286 287 time.Sleep(time.Second) 288 panic(err) 289 } 290 291 utils.EnableDebugLogForTest() 292 293 return member 294 } 295 296 func (me *TestHelper) TearDown() { 297 me.App.Shutdown() 298 os.Remove(me.tempConfigPath) 299 if err := recover(); err != nil { 300 StopTestStore() 301 panic(err) 302 } 303 if me.tempWorkspace != "" { 304 os.RemoveAll(me.tempWorkspace) 305 } 306 } 307 308 type mockPluginSupervisor struct { 309 hooks plugin.Hooks 310 } 311 312 func (s *mockPluginSupervisor) Start(api plugin.API) error { 313 return s.hooks.OnActivate(api) 314 } 315 316 func (s *mockPluginSupervisor) Stop() error { 317 return nil 318 } 319 320 func (s *mockPluginSupervisor) Hooks() plugin.Hooks { 321 return s.hooks 322 } 323 324 func (me *TestHelper) InstallPlugin(manifest *model.Manifest, hooks plugin.Hooks) { 325 if me.tempWorkspace == "" { 326 dir, err := ioutil.TempDir("", "apptest") 327 if err != nil { 328 panic(err) 329 } 330 me.tempWorkspace = dir 331 } 332 333 pluginDir := filepath.Join(me.tempWorkspace, "plugins") 334 webappDir := filepath.Join(me.tempWorkspace, "webapp") 335 me.App.InitPlugins(pluginDir, webappDir, func(bundle *model.BundleInfo) (plugin.Supervisor, error) { 336 if hooks, ok := me.pluginHooks[bundle.Manifest.Id]; ok { 337 return &mockPluginSupervisor{hooks}, nil 338 } 339 return pluginenv.DefaultSupervisorProvider(bundle) 340 }) 341 342 me.pluginHooks[manifest.Id] = hooks 343 344 manifestCopy := *manifest 345 if manifestCopy.Backend == nil { 346 manifestCopy.Backend = &model.ManifestBackend{} 347 } 348 manifestBytes, err := json.Marshal(&manifestCopy) 349 if err != nil { 350 panic(err) 351 } 352 353 if err := os.MkdirAll(filepath.Join(pluginDir, manifest.Id), 0700); err != nil { 354 panic(err) 355 } 356 357 if err := ioutil.WriteFile(filepath.Join(pluginDir, manifest.Id, "plugin.json"), manifestBytes, 0600); err != nil { 358 panic(err) 359 } 360 } 361 362 func (me *TestHelper) ResetRoleMigration() { 363 if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Roles"); err != nil { 364 panic(err) 365 } 366 367 testClusterInterface.sendClearRoleCacheMessage() 368 369 if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Systems where Name = :Name", map[string]interface{}{"Name": ADVANCED_PERMISSIONS_MIGRATION_KEY}); err != nil { 370 panic(err) 371 } 372 } 373 374 type FakeClusterInterface struct { 375 clusterMessageHandler einterfaces.ClusterMessageHandler 376 } 377 378 func (me *FakeClusterInterface) StartInterNodeCommunication() {} 379 func (me *FakeClusterInterface) StopInterNodeCommunication() {} 380 func (me *FakeClusterInterface) RegisterClusterMessageHandler(event string, crm einterfaces.ClusterMessageHandler) { 381 me.clusterMessageHandler = crm 382 } 383 func (me *FakeClusterInterface) GetClusterId() string { return "" } 384 func (me *FakeClusterInterface) IsLeader() bool { return false } 385 func (me *FakeClusterInterface) GetMyClusterInfo() *model.ClusterInfo { return nil } 386 func (me *FakeClusterInterface) GetClusterInfos() []*model.ClusterInfo { return nil } 387 func (me *FakeClusterInterface) SendClusterMessage(cluster *model.ClusterMessage) {} 388 func (me *FakeClusterInterface) NotifyMsg(buf []byte) {} 389 func (me *FakeClusterInterface) GetClusterStats() ([]*model.ClusterStats, *model.AppError) { 390 return nil, nil 391 } 392 func (me *FakeClusterInterface) GetLogs(page, perPage int) ([]string, *model.AppError) { 393 return []string{}, nil 394 } 395 func (me *FakeClusterInterface) ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError { 396 return nil 397 } 398 func (me *FakeClusterInterface) sendClearRoleCacheMessage() { 399 me.clusterMessageHandler(&model.ClusterMessage{ 400 Event: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES, 401 }) 402 }