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 }