github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/cmd/mattermost/commands/server_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"io/ioutil"
     8  	"net"
     9  	"os"
    10  	"syscall"
    11  	"testing"
    12  
    13  	"github.com/mattermost/mattermost-server/v5/config"
    14  	"github.com/mattermost/mattermost-server/v5/jobs"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  const (
    19  	UnitTestListeningPort = ":0"
    20  )
    21  
    22  type ServerTestHelper struct {
    23  	disableConfigWatch bool
    24  	interruptChan      chan os.Signal
    25  	originalInterval   int
    26  }
    27  
    28  func SetupServerTest(t testing.TB) *ServerTestHelper {
    29  	if testing.Short() {
    30  		t.SkipNow()
    31  	}
    32  	// Build a channel that will be used by the server to receive system signals...
    33  	interruptChan := make(chan os.Signal, 1)
    34  	// ...and sent it immediately a SIGINT value.
    35  	// This will make the server loop stop as soon as it started successfully.
    36  	interruptChan <- syscall.SIGINT
    37  
    38  	// Let jobs poll for termination every 0.2s (instead of every 15s by default)
    39  	// Otherwise we would have to wait the whole polling duration before the test
    40  	// terminates.
    41  	originalInterval := jobs.DEFAULT_WATCHER_POLLING_INTERVAL
    42  	jobs.DEFAULT_WATCHER_POLLING_INTERVAL = 200
    43  
    44  	th := &ServerTestHelper{
    45  		disableConfigWatch: true,
    46  		interruptChan:      interruptChan,
    47  		originalInterval:   originalInterval,
    48  	}
    49  	return th
    50  }
    51  
    52  func (th *ServerTestHelper) TearDownServerTest() {
    53  	jobs.DEFAULT_WATCHER_POLLING_INTERVAL = th.originalInterval
    54  }
    55  
    56  func TestRunServerSuccess(t *testing.T) {
    57  	th := SetupServerTest(t)
    58  	defer th.TearDownServerTest()
    59  
    60  	configStore, err := config.NewMemoryStore()
    61  	require.NoError(t, err)
    62  
    63  	// Use non-default listening port in case another server instance is already running.
    64  	*configStore.Get().ServiceSettings.ListenAddress = UnitTestListeningPort
    65  
    66  	err = runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
    67  	require.NoError(t, err)
    68  }
    69  
    70  func TestRunServerSystemdNotification(t *testing.T) {
    71  	th := SetupServerTest(t)
    72  	defer th.TearDownServerTest()
    73  
    74  	// Get a random temporary filename for using as a mock systemd socket
    75  	socketFile, err := ioutil.TempFile("", "mattermost-systemd-mock-socket-")
    76  	if err != nil {
    77  		panic(err)
    78  	}
    79  	socketPath := socketFile.Name()
    80  	os.Remove(socketPath)
    81  
    82  	// Set the socket path in the process environment
    83  	originalSocket := os.Getenv("NOTIFY_SOCKET")
    84  	os.Setenv("NOTIFY_SOCKET", socketPath)
    85  	defer os.Setenv("NOTIFY_SOCKET", originalSocket)
    86  
    87  	// Open the socket connection
    88  	addr := &net.UnixAddr{
    89  		Name: socketPath,
    90  		Net:  "unixgram",
    91  	}
    92  	connection, err := net.ListenUnixgram("unixgram", addr)
    93  	if err != nil {
    94  		panic(err)
    95  	}
    96  	defer connection.Close()
    97  	defer os.Remove(socketPath)
    98  
    99  	// Listen for socket data
   100  	socketReader := make(chan string)
   101  	go func(ch chan string) {
   102  		buffer := make([]byte, 512)
   103  		count, readErr := connection.Read(buffer)
   104  		if readErr != nil {
   105  			panic(readErr)
   106  		}
   107  		data := buffer[0:count]
   108  		ch <- string(data)
   109  	}(socketReader)
   110  
   111  	configStore, err := config.NewMemoryStore()
   112  	require.NoError(t, err)
   113  
   114  	// Use non-default listening port in case another server instance is already running.
   115  	*configStore.Get().ServiceSettings.ListenAddress = UnitTestListeningPort
   116  
   117  	// Start and stop the server
   118  	err = runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
   119  	require.NoError(t, err)
   120  
   121  	// Ensure the notification has been sent on the socket and is correct
   122  	notification := <-socketReader
   123  	require.Equal(t, notification, "READY=1")
   124  }
   125  
   126  func TestRunServerNoSystemd(t *testing.T) {
   127  	th := SetupServerTest(t)
   128  	defer th.TearDownServerTest()
   129  
   130  	// Temporarily remove any Systemd socket defined in the environment
   131  	originalSocket := os.Getenv("NOTIFY_SOCKET")
   132  	os.Unsetenv("NOTIFY_SOCKET")
   133  	defer os.Setenv("NOTIFY_SOCKET", originalSocket)
   134  
   135  	configStore, err := config.NewMemoryStore()
   136  	require.NoError(t, err)
   137  
   138  	// Use non-default listening port in case another server instance is already running.
   139  	*configStore.Get().ServiceSettings.ListenAddress = UnitTestListeningPort
   140  
   141  	err = runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
   142  	require.NoError(t, err)
   143  }