github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/plugin/health_check_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package plugin
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/mattermost/mattermost-server/v5/mlog"
    16  	"github.com/mattermost/mattermost-server/v5/model"
    17  	"github.com/mattermost/mattermost-server/v5/utils"
    18  )
    19  
    20  func TestPluginHealthCheck(t *testing.T) {
    21  	for name, f := range map[string]func(*testing.T){
    22  		"PluginHealthCheck_Success": testPluginHealthCheckSuccess,
    23  		"PluginHealthCheck_Panic":   testPluginHealthCheckPanic,
    24  	} {
    25  		t.Run(name, f)
    26  	}
    27  }
    28  
    29  func testPluginHealthCheckSuccess(t *testing.T) {
    30  	dir, err := ioutil.TempDir("", "")
    31  	require.NoError(t, err)
    32  	defer os.RemoveAll(dir)
    33  
    34  	backend := filepath.Join(dir, "backend.exe")
    35  	utils.CompileGo(t, `
    36  		package main
    37  
    38  		import (
    39  			"github.com/mattermost/mattermost-server/v5/plugin"
    40  		)
    41  
    42  		type MyPlugin struct {
    43  			plugin.MattermostPlugin
    44  		}
    45  
    46  		func main() {
    47  			plugin.ClientMain(&MyPlugin{})
    48  		}
    49  	`, backend)
    50  
    51  	err = ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "backend": {"executable": "backend.exe"}}`), 0600)
    52  	require.NoError(t, err)
    53  
    54  	bundle := model.BundleInfoForPath(dir)
    55  	log := mlog.NewLogger(&mlog.LoggerConfiguration{
    56  		EnableConsole: true,
    57  		ConsoleJson:   true,
    58  		ConsoleLevel:  "error",
    59  		EnableFile:    false,
    60  	})
    61  
    62  	supervisor, err := newSupervisor(bundle, nil, log, nil)
    63  	require.Nil(t, err)
    64  	require.NotNil(t, supervisor)
    65  	defer supervisor.Shutdown()
    66  
    67  	err = supervisor.PerformHealthCheck()
    68  	require.Nil(t, err)
    69  }
    70  
    71  func testPluginHealthCheckPanic(t *testing.T) {
    72  	dir, err := ioutil.TempDir("", "")
    73  	require.NoError(t, err)
    74  	defer os.RemoveAll(dir)
    75  
    76  	backend := filepath.Join(dir, "backend.exe")
    77  	utils.CompileGo(t, `
    78  		package main
    79  
    80  		import (
    81  			"github.com/mattermost/mattermost-server/v5/model"
    82  			"github.com/mattermost/mattermost-server/v5/plugin"
    83  		)
    84  
    85  		type MyPlugin struct {
    86  			plugin.MattermostPlugin
    87  		}
    88  
    89  		func (p *MyPlugin) MessageWillBePosted(c *plugin.Context, post *model.Post) (*model.Post, string) {
    90  			panic("Uncaught error")
    91  		}
    92  
    93  		func main() {
    94  			plugin.ClientMain(&MyPlugin{})
    95  		}
    96  	`, backend)
    97  
    98  	err = ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "backend": {"executable": "backend.exe"}}`), 0600)
    99  	require.NoError(t, err)
   100  
   101  	bundle := model.BundleInfoForPath(dir)
   102  	log := mlog.NewLogger(&mlog.LoggerConfiguration{
   103  		EnableConsole: true,
   104  		ConsoleJson:   true,
   105  		ConsoleLevel:  "error",
   106  		EnableFile:    false,
   107  	})
   108  
   109  	supervisor, err := newSupervisor(bundle, nil, log, nil)
   110  	require.Nil(t, err)
   111  	require.NotNil(t, supervisor)
   112  	defer supervisor.Shutdown()
   113  
   114  	err = supervisor.PerformHealthCheck()
   115  	require.Nil(t, err)
   116  
   117  	supervisor.hooks.MessageWillBePosted(&Context{}, &model.Post{})
   118  
   119  	err = supervisor.PerformHealthCheck()
   120  	require.NotNil(t, err)
   121  }
   122  
   123  func TestShouldDeactivatePlugin(t *testing.T) {
   124  	// No failures, don't restart
   125  	ftime := []time.Time{}
   126  	result := shouldDeactivatePlugin(ftime)
   127  	require.Equal(t, false, result)
   128  
   129  	now := time.Now()
   130  
   131  	// Failures are recent enough to restart
   132  	ftime = []time.Time{}
   133  	ftime = append(ftime, now.Add(-HealthCheckDeactivationWindow/10*2))
   134  	ftime = append(ftime, now.Add(-HealthCheckDeactivationWindow/10))
   135  	ftime = append(ftime, now)
   136  
   137  	result = shouldDeactivatePlugin(ftime)
   138  	require.Equal(t, true, result)
   139  
   140  	// Failures are too spaced out to warrant a restart
   141  	ftime = []time.Time{}
   142  	ftime = append(ftime, now.Add(-HealthCheckDeactivationWindow*2))
   143  	ftime = append(ftime, now.Add(-HealthCheckDeactivationWindow*1))
   144  	ftime = append(ftime, now)
   145  
   146  	result = shouldDeactivatePlugin(ftime)
   147  	require.Equal(t, false, result)
   148  
   149  	// Not enough failures are present to warrant a restart
   150  	ftime = []time.Time{}
   151  	ftime = append(ftime, now.Add(-HealthCheckDeactivationWindow/10))
   152  	ftime = append(ftime, now)
   153  
   154  	result = shouldDeactivatePlugin(ftime)
   155  	require.Equal(t, false, result)
   156  }