github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/app/busy_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/mattermost/mattermost-server/v5/einterfaces" 12 "github.com/mattermost/mattermost-server/v5/model" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestBusySet(t *testing.T) { 17 cluster := &ClusterMock{Busy: &Busy{}} 18 busy := NewBusy(cluster) 19 20 isNotBusy := func() bool { 21 return !busy.IsBusy() 22 } 23 24 require.False(t, busy.IsBusy()) 25 26 busy.Set(time.Millisecond * 100) 27 require.True(t, busy.IsBusy()) 28 require.True(t, compareBusyState(t, busy, cluster.Busy)) 29 // should automatically expire after 100ms. 30 require.Eventually(t, isNotBusy, time.Second*15, time.Millisecond*20) 31 // allow a moment for cluster to sync. 32 require.Eventually(t, func() bool { return compareBusyState(t, busy, cluster.Busy) }, time.Second*15, time.Millisecond*20) 33 34 // test set after auto expiry. 35 busy.Set(time.Second * 30) 36 require.True(t, busy.IsBusy()) 37 require.True(t, compareBusyState(t, busy, cluster.Busy)) 38 expire := busy.Expires() 39 require.Greater(t, expire.Unix(), time.Now().Add(time.Second*10).Unix()) 40 41 // test extending existing expiry 42 busy.Set(time.Minute * 5) 43 require.True(t, busy.IsBusy()) 44 require.True(t, compareBusyState(t, busy, cluster.Busy)) 45 expire = busy.Expires() 46 require.Greater(t, expire.Unix(), time.Now().Add(time.Minute*2).Unix()) 47 48 busy.Clear() 49 require.False(t, busy.IsBusy()) 50 require.True(t, compareBusyState(t, busy, cluster.Busy)) 51 } 52 53 func TestBusyExpires(t *testing.T) { 54 cluster := &ClusterMock{Busy: &Busy{}} 55 busy := NewBusy(cluster) 56 57 isNotBusy := func() bool { 58 return !busy.IsBusy() 59 } 60 61 // get expiry before it is set 62 expire := busy.Expires() 63 // should be time.Time zero value 64 require.Equal(t, time.Time{}.Unix(), expire.Unix()) 65 66 // get expiry after it is set 67 busy.Set(time.Minute * 5) 68 expire = busy.Expires() 69 require.Greater(t, expire.Unix(), time.Now().Add(time.Minute*2).Unix()) 70 require.True(t, compareBusyState(t, busy, cluster.Busy)) 71 72 // get expiry after clear 73 busy.Clear() 74 expire = busy.Expires() 75 // should be time.Time zero value 76 require.Equal(t, time.Time{}.Unix(), expire.Unix()) 77 require.True(t, compareBusyState(t, busy, cluster.Busy)) 78 79 // get expiry after auto-expire 80 busy.Set(time.Millisecond * 100) 81 require.Eventually(t, isNotBusy, time.Second*5, time.Millisecond*20) 82 expire = busy.Expires() 83 // should be time.Time zero value 84 require.Equal(t, time.Time{}.Unix(), expire.Unix()) 85 // allow a moment for cluster to sync 86 require.Eventually(t, func() bool { return compareBusyState(t, busy, cluster.Busy) }, time.Second*15, time.Millisecond*20) 87 } 88 89 func compareBusyState(t *testing.T, busy1 *Busy, busy2 *Busy) bool { 90 t.Helper() 91 if busy1.IsBusy() != busy2.IsBusy() { 92 t.Logf("busy1:%s; busy2:%s\n", busy1.ToJson(), busy2.ToJson()) 93 return false 94 } 95 if busy1.Expires().Unix() != busy2.Expires().Unix() { 96 t.Logf("busy1:%s; busy2:%s\n", busy1.ToJson(), busy2.ToJson()) 97 return false 98 } 99 return true 100 } 101 102 // ClusterMock simulates the busy state of a cluster. 103 type ClusterMock struct { 104 Busy *Busy 105 } 106 107 func (c *ClusterMock) SendClusterMessage(msg *model.ClusterMessage) { 108 sbs := model.ServerBusyStateFromJson(strings.NewReader(msg.Data)) 109 c.Busy.ClusterEventChanged(sbs) 110 } 111 112 func (c *ClusterMock) StartInterNodeCommunication() {} 113 func (c *ClusterMock) StopInterNodeCommunication() {} 114 func (c *ClusterMock) RegisterClusterMessageHandler(event string, crm einterfaces.ClusterMessageHandler) { 115 } 116 func (c *ClusterMock) GetClusterId() string { return "cluster_mock" } 117 func (c *ClusterMock) IsLeader() bool { return false } 118 func (c *ClusterMock) GetMyClusterInfo() *model.ClusterInfo { return nil } 119 func (c *ClusterMock) GetClusterInfos() []*model.ClusterInfo { return nil } 120 func (c *ClusterMock) NotifyMsg(buf []byte) {} 121 func (c *ClusterMock) GetClusterStats() ([]*model.ClusterStats, *model.AppError) { return nil, nil } 122 func (c *ClusterMock) GetLogs(page, perPage int) ([]string, *model.AppError) { return nil, nil } 123 func (c *ClusterMock) GetPluginStatuses() (model.PluginStatuses, *model.AppError) { return nil, nil } 124 func (c *ClusterMock) ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError { 125 return nil 126 } 127 func (c *ClusterMock) HealthScore() int { return 0 }