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 }