Summary We need a pointer to a pointer to set the original pointer to nil The original task was not being set to nil (the local variable containing the pointer was being set to nil). The cancel function was being called even though the task had already been cancelled. This repeated cancellation was causing a panic because we were trying to close a channel that had already been closed the first time the task was cancelled. Ticket Link https://mattermost.atlassian.net/browse/MM-46402
578 строки
17 KiB
Go
578 строки
17 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"bufio"
|
|
"crypto/tls"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/getsentry/sentry-go"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost-server/v6/app/platform"
|
|
"github.com/mattermost/mattermost-server/v6/config"
|
|
"github.com/mattermost/mattermost-server/v6/model"
|
|
"github.com/mattermost/mattermost-server/v6/shared/filestore"
|
|
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
|
"github.com/mattermost/mattermost-server/v6/store/storetest"
|
|
"github.com/mattermost/mattermost-server/v6/utils/fileutils"
|
|
)
|
|
|
|
func newServerWithConfig(t *testing.T, f func(cfg *model.Config)) (*Server, error) {
|
|
configStore, err := config.NewMemoryStore()
|
|
require.NoError(t, err)
|
|
store, err := config.NewStoreFromBacking(configStore, nil, false)
|
|
require.NoError(t, err)
|
|
cfg := store.Get()
|
|
f(cfg)
|
|
|
|
store.Set(cfg)
|
|
|
|
return NewServer(ConfigStore(store))
|
|
}
|
|
|
|
func TestStartServerSuccess(t *testing.T) {
|
|
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
serverErr := s.Start()
|
|
|
|
client := &http.Client{}
|
|
checkEndpoint(t, client, "http://localhost:"+strconv.Itoa(s.ListenAddr.Port)+"/")
|
|
|
|
s.Shutdown()
|
|
require.NoError(t, serverErr)
|
|
}
|
|
|
|
func TestReadReplicaDisabledBasedOnLicense(t *testing.T) {
|
|
cfg := model.Config{}
|
|
cfg.SetDefaults()
|
|
driverName := os.Getenv("MM_SQLSETTINGS_DRIVERNAME")
|
|
if driverName == "" {
|
|
driverName = model.DatabaseDriverPostgres
|
|
}
|
|
dsn := ""
|
|
if driverName == model.DatabaseDriverPostgres {
|
|
dsn = os.Getenv("TEST_DATABASE_POSTGRESQL_DSN")
|
|
} else {
|
|
dsn = os.Getenv("TEST_DATABASE_MYSQL_DSN")
|
|
}
|
|
cfg.SqlSettings = *storetest.MakeSqlSettings(driverName, false)
|
|
if dsn != "" {
|
|
cfg.SqlSettings.DataSource = &dsn
|
|
}
|
|
cfg.SqlSettings.DataSourceReplicas = []string{*cfg.SqlSettings.DataSource}
|
|
cfg.SqlSettings.DataSourceSearchReplicas = []string{*cfg.SqlSettings.DataSource}
|
|
|
|
t.Run("Read Replicas with no License", func(t *testing.T) {
|
|
s, err := NewServer(func(server *Server) error {
|
|
configStore := config.NewTestMemoryStore()
|
|
configStore.Set(&cfg)
|
|
var err error
|
|
server.platform, err = platform.New(platform.ServiceConfig{
|
|
ConfigStore: configStore,
|
|
})
|
|
require.NoError(t, err)
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
defer s.Shutdown()
|
|
require.Same(t, s.sqlStore.GetMasterX(), s.sqlStore.GetReplicaX())
|
|
require.Len(t, s.platform.Config().SqlSettings.DataSourceReplicas, 1)
|
|
})
|
|
|
|
t.Run("Read Replicas With License", func(t *testing.T) {
|
|
s, err := NewServer(func(server *Server) error {
|
|
configStore := config.NewTestMemoryStore()
|
|
configStore.Set(&cfg)
|
|
var err error
|
|
server.platform, err = platform.New(platform.ServiceConfig{
|
|
ConfigStore: configStore,
|
|
})
|
|
require.NoError(t, err)
|
|
server.licenseValue.Store(model.NewTestLicense())
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
defer s.Shutdown()
|
|
require.NotSame(t, s.sqlStore.GetMasterX(), s.sqlStore.GetReplicaX())
|
|
require.Len(t, s.platform.Config().SqlSettings.DataSourceReplicas, 1)
|
|
})
|
|
|
|
t.Run("Search Replicas with no License", func(t *testing.T) {
|
|
s, err := NewServer(func(server *Server) error {
|
|
configStore := config.NewTestMemoryStore()
|
|
configStore.Set(&cfg)
|
|
var err error
|
|
server.platform, err = platform.New(platform.ServiceConfig{
|
|
ConfigStore: configStore,
|
|
})
|
|
require.NoError(t, err)
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
defer s.Shutdown()
|
|
require.Same(t, s.sqlStore.GetMasterX(), s.sqlStore.GetSearchReplicaX())
|
|
require.Len(t, s.platform.Config().SqlSettings.DataSourceSearchReplicas, 1)
|
|
})
|
|
|
|
t.Run("Search Replicas With License", func(t *testing.T) {
|
|
s, err := NewServer(func(server *Server) error {
|
|
configStore := config.NewTestMemoryStore()
|
|
configStore.Set(&cfg)
|
|
var err error
|
|
server.platform, err = platform.New(platform.ServiceConfig{
|
|
ConfigStore: configStore,
|
|
})
|
|
require.NoError(t, err)
|
|
server.licenseValue.Store(model.NewTestLicense())
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
defer s.Shutdown()
|
|
require.NotSame(t, s.sqlStore.GetMasterX(), s.sqlStore.GetSearchReplicaX())
|
|
require.Len(t, s.platform.Config().SqlSettings.DataSourceSearchReplicas, 1)
|
|
})
|
|
}
|
|
|
|
func TestStartServerPortUnavailable(t *testing.T) {
|
|
s, err := NewServer()
|
|
require.NoError(t, err)
|
|
|
|
// Listen on the next available port
|
|
listener, err := net.Listen("tcp", ":0")
|
|
require.NoError(t, err)
|
|
|
|
// Attempt to listen on the port used above.
|
|
s.platform.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.ListenAddress = listener.Addr().String()
|
|
})
|
|
|
|
serverErr := s.Start()
|
|
s.Shutdown()
|
|
require.Error(t, serverErr)
|
|
}
|
|
|
|
func TestStartServerNoS3Bucket(t *testing.T) {
|
|
s3Host := os.Getenv("CI_MINIO_HOST")
|
|
if s3Host == "" {
|
|
s3Host = "localhost"
|
|
}
|
|
|
|
s3Port := os.Getenv("CI_MINIO_PORT")
|
|
if s3Port == "" {
|
|
s3Port = "9000"
|
|
}
|
|
|
|
s3Endpoint := fmt.Sprintf("%s:%s", s3Host, s3Port)
|
|
|
|
s, err := NewServer(func(server *Server) error {
|
|
configStore, _ := config.NewFileStore("config.json", true)
|
|
store, _ := config.NewStoreFromBacking(configStore, nil, false)
|
|
var err error
|
|
server.platform, err = platform.New(platform.ServiceConfig{
|
|
ConfigStore: store,
|
|
})
|
|
require.NoError(t, err)
|
|
server.platform.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.FileSettings = model.FileSettings{
|
|
DriverName: model.NewString(model.ImageDriverS3),
|
|
AmazonS3AccessKeyId: model.NewString(model.MinioAccessKey),
|
|
AmazonS3SecretAccessKey: model.NewString(model.MinioSecretKey),
|
|
AmazonS3Bucket: model.NewString("nosuchbucket"),
|
|
AmazonS3Endpoint: model.NewString(s3Endpoint),
|
|
AmazonS3Region: model.NewString(""),
|
|
AmazonS3PathPrefix: model.NewString(""),
|
|
AmazonS3SSL: model.NewBool(false),
|
|
}
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
})
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, s.Start())
|
|
defer s.Shutdown()
|
|
|
|
// ensure that a new bucket was created
|
|
err = s.FileBackend().(*filestore.S3FileBackend).TestConnection()
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestStartServerTLSSuccess(t *testing.T) {
|
|
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
|
testDir, _ := fileutils.FindDir("tests")
|
|
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
*cfg.ServiceSettings.ConnectionSecurity = "TLS"
|
|
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
|
|
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
serverErr := s.Start()
|
|
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
checkEndpoint(t, client, "https://localhost:"+strconv.Itoa(s.ListenAddr.Port)+"/")
|
|
|
|
s.Shutdown()
|
|
require.NoError(t, serverErr)
|
|
}
|
|
|
|
func TestDatabaseTypeAndMattermostVersion(t *testing.T) {
|
|
sqlDrivernameEnvironment := os.Getenv("MM_SQLSETTINGS_DRIVERNAME")
|
|
|
|
if sqlDrivernameEnvironment != "" {
|
|
defer os.Setenv("MM_SQLSETTINGS_DRIVERNAME", sqlDrivernameEnvironment)
|
|
} else {
|
|
defer os.Unsetenv("MM_SQLSETTINGS_DRIVERNAME")
|
|
}
|
|
|
|
os.Setenv("MM_SQLSETTINGS_DRIVERNAME", "postgres")
|
|
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
databaseType, mattermostVersion := th.Server.DatabaseTypeAndSchemaVersion()
|
|
assert.Equal(t, "postgres", databaseType)
|
|
assert.GreaterOrEqual(t, mattermostVersion, strconv.Itoa(1))
|
|
|
|
os.Setenv("MM_SQLSETTINGS_DRIVERNAME", "mysql")
|
|
|
|
th2 := Setup(t)
|
|
defer th2.TearDown()
|
|
|
|
databaseType, mattermostVersion = th2.Server.DatabaseTypeAndSchemaVersion()
|
|
assert.Equal(t, "mysql", databaseType)
|
|
assert.GreaterOrEqual(t, mattermostVersion, strconv.Itoa(1))
|
|
}
|
|
|
|
func TestStartServerTLSVersion(t *testing.T) {
|
|
configStore, _ := config.NewMemoryStore()
|
|
store, _ := config.NewStoreFromBacking(configStore, nil, false)
|
|
cfg := store.Get()
|
|
testDir, _ := fileutils.FindDir("tests")
|
|
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
*cfg.ServiceSettings.ConnectionSecurity = "TLS"
|
|
*cfg.ServiceSettings.TLSMinVer = "1.2"
|
|
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
|
|
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
|
|
|
|
store.Set(cfg)
|
|
|
|
s, err := NewServer(ConfigStore(store))
|
|
require.NoError(t, err)
|
|
|
|
serverErr := s.Start()
|
|
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
MaxVersion: tls.VersionTLS11,
|
|
},
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
err = checkEndpoint(t, client, "https://localhost:"+strconv.Itoa(s.ListenAddr.Port)+"/")
|
|
require.Error(t, err)
|
|
|
|
client.Transport = &http.Transport{
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
},
|
|
}
|
|
|
|
err = checkEndpoint(t, client, "https://localhost:"+strconv.Itoa(s.ListenAddr.Port)+"/")
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected nil, got %s", err)
|
|
}
|
|
|
|
s.Shutdown()
|
|
require.NoError(t, serverErr)
|
|
}
|
|
|
|
func TestStartServerTLSOverwriteCipher(t *testing.T) {
|
|
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
|
testDir, _ := fileutils.FindDir("tests")
|
|
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
*cfg.ServiceSettings.ConnectionSecurity = "TLS"
|
|
cfg.ServiceSettings.TLSOverwriteCiphers = []string{
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
}
|
|
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
|
|
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = s.Start()
|
|
require.NoError(t, err)
|
|
|
|
defer s.Shutdown()
|
|
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
|
|
},
|
|
MaxVersion: tls.VersionTLS12,
|
|
},
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
err = checkEndpoint(t, client, "https://localhost:"+strconv.Itoa(s.ListenAddr.Port)+"/")
|
|
require.Error(t, err, "Expected error due to Cipher mismatch")
|
|
require.Contains(t, err.Error(), "remote error: tls: handshake failure", "Expected protocol version error")
|
|
|
|
client.Transport = &http.Transport{
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
},
|
|
MaxVersion: tls.VersionTLS12,
|
|
},
|
|
}
|
|
|
|
err = checkEndpoint(t, client, "https://localhost:"+strconv.Itoa(s.ListenAddr.Port)+"/")
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func checkEndpoint(t *testing.T, client *http.Client, url string) error {
|
|
res, err := client.Get(url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
if res.StatusCode != http.StatusNotFound {
|
|
t.Errorf("Response code was %d; want %d", res.StatusCode, http.StatusNotFound)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func TestPanicLog(t *testing.T) {
|
|
// Creating a temp dir for log
|
|
tmpDir, err := os.MkdirTemp("", "mlog-test")
|
|
require.NoError(t, err, "cannot create tmp dir for log file")
|
|
defer func() {
|
|
err2 := os.RemoveAll(tmpDir)
|
|
assert.NoError(t, err2)
|
|
}()
|
|
|
|
// Creating logger to log to console and temp file
|
|
logger, _ := mlog.NewLogger()
|
|
|
|
logSettings := model.NewLogSettings()
|
|
logSettings.EnableConsole = model.NewBool(true)
|
|
logSettings.ConsoleJson = model.NewBool(true)
|
|
logSettings.EnableFile = model.NewBool(true)
|
|
logSettings.FileLocation = &tmpDir
|
|
logSettings.FileLevel = &mlog.LvlInfo.Name
|
|
|
|
cfg, err := config.MloggerConfigFromLoggerConfig(logSettings, nil, config.GetLogFileLocation)
|
|
require.NoError(t, err)
|
|
err = logger.ConfigureTargets(cfg, nil)
|
|
require.NoError(t, err)
|
|
logger.LockConfiguration()
|
|
|
|
// Creating a server with logger
|
|
s, err := NewServer(SetLogger(logger))
|
|
require.NoError(t, err)
|
|
|
|
// Route for just panicking
|
|
s.Router.HandleFunc("/panic", func(writer http.ResponseWriter, request *http.Request) {
|
|
s.Log.Info("inside panic handler")
|
|
panic("log this panic")
|
|
})
|
|
|
|
testDir, _ := fileutils.FindDir("tests")
|
|
s.platform.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
*cfg.ServiceSettings.ConnectionSecurity = "TLS"
|
|
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
|
|
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
|
|
})
|
|
serverErr := s.Start()
|
|
require.NoError(t, serverErr)
|
|
|
|
// Calling panic route
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
client.Get("https://localhost:" + strconv.Itoa(s.ListenAddr.Port) + "/panic")
|
|
|
|
err = logger.Flush()
|
|
assert.NoError(t, err, "flush should succeed")
|
|
s.Shutdown()
|
|
|
|
// Checking whether panic was logged
|
|
var panicLogged = false
|
|
var infoLogged = false
|
|
|
|
logFile, err := os.Open(config.GetLogFileLocation(tmpDir))
|
|
require.NoError(t, err, "cannot open log file")
|
|
|
|
_, err = logFile.Seek(0, 0)
|
|
require.NoError(t, err)
|
|
|
|
scanner := bufio.NewScanner(logFile)
|
|
for scanner.Scan() {
|
|
if !infoLogged && strings.Contains(scanner.Text(), "inside panic handler") {
|
|
infoLogged = true
|
|
}
|
|
if strings.Contains(scanner.Text(), "log this panic") {
|
|
panicLogged = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !infoLogged {
|
|
t.Error("Info log line was supposed to be logged")
|
|
}
|
|
|
|
if !panicLogged {
|
|
t.Error("Panic was supposed to be logged")
|
|
}
|
|
}
|
|
|
|
func TestSentry(t *testing.T) {
|
|
if testing.Short() {
|
|
t.SkipNow()
|
|
}
|
|
|
|
client := &http.Client{Timeout: 5 * time.Second, Transport: &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}}
|
|
testDir, _ := fileutils.FindDir("tests")
|
|
|
|
t.Run("sentry is disabled, should not receive a report", func(t *testing.T) {
|
|
data := make(chan bool, 1)
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
t.Log("Received sentry request for some reason")
|
|
data <- true
|
|
}))
|
|
defer server.Close()
|
|
|
|
// make sure we don't report anything when sentry is disabled
|
|
_, port, _ := net.SplitHostPort(server.Listener.Addr().String())
|
|
dsn, err := sentry.NewDsn(fmt.Sprintf("http://test:test@localhost:%s/123", port))
|
|
require.NoError(t, err)
|
|
SentryDSN = dsn.String()
|
|
|
|
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
*cfg.LogSettings.EnableSentry = false
|
|
*cfg.ServiceSettings.ConnectionSecurity = "TLS"
|
|
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
|
|
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
|
|
*cfg.LogSettings.EnableDiagnostics = true
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
s.Router.HandleFunc("/panic", func(writer http.ResponseWriter, request *http.Request) {
|
|
panic("log this panic")
|
|
})
|
|
|
|
require.NoError(t, s.Start())
|
|
defer s.Shutdown()
|
|
|
|
resp, err := client.Get("https://localhost:" + strconv.Itoa(s.ListenAddr.Port) + "/panic")
|
|
require.Nil(t, resp)
|
|
require.True(t, errors.Is(err, io.EOF), fmt.Sprintf("unexpected error: %s", err))
|
|
|
|
sentry.Flush(time.Second)
|
|
select {
|
|
case <-data:
|
|
require.Fail(t, "Sentry received a message, even though it's disabled!")
|
|
case <-time.After(time.Second):
|
|
t.Log("Sentry request didn't arrive. Good!")
|
|
}
|
|
})
|
|
|
|
t.Run("sentry is enabled, report should be received", func(t *testing.T) {
|
|
data := make(chan bool, 1)
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
t.Log("Received sentry request!")
|
|
data <- true
|
|
}))
|
|
defer server.Close()
|
|
|
|
_, port, _ := net.SplitHostPort(server.Listener.Addr().String())
|
|
dsn, err := sentry.NewDsn(fmt.Sprintf("http://test:test@localhost:%s/123", port))
|
|
require.NoError(t, err)
|
|
SentryDSN = dsn.String()
|
|
|
|
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.ListenAddress = ":0"
|
|
*cfg.ServiceSettings.ConnectionSecurity = "TLS"
|
|
*cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem")
|
|
*cfg.ServiceSettings.TLSCertFile = path.Join(testDir, "tls_test_cert.pem")
|
|
*cfg.LogSettings.EnableSentry = true
|
|
*cfg.LogSettings.EnableDiagnostics = true
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Route for just panicking
|
|
s.Router.HandleFunc("/panic", func(writer http.ResponseWriter, request *http.Request) {
|
|
panic("log this panic")
|
|
})
|
|
|
|
require.NoError(t, s.Start())
|
|
defer s.Shutdown()
|
|
|
|
resp, err := client.Get("https://localhost:" + strconv.Itoa(s.ListenAddr.Port) + "/panic")
|
|
require.Nil(t, resp)
|
|
require.True(t, errors.Is(err, io.EOF), fmt.Sprintf("unexpected error: %s", err))
|
|
|
|
sentry.Flush(time.Second)
|
|
select {
|
|
case <-data:
|
|
t.Log("Sentry request arrived. Good!")
|
|
case <-time.After(time.Second * 10):
|
|
require.Fail(t, "Sentry report didn't arrive")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCancelTaskSetsTaskToNil(t *testing.T) {
|
|
var taskMut sync.Mutex
|
|
task := model.CreateRecurringTaskFromNextIntervalTime("a test task", func() {}, 5*time.Minute)
|
|
require.NotNil(t, task)
|
|
cancelTask(&taskMut, &task)
|
|
require.Nil(t, task)
|
|
require.NotPanics(t, func() { cancelTask(&taskMut, &task) })
|
|
}
|