mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
Currently in tests, we have calls to os.Remove and os.RemoveAll where we don't check the returned error. This hides useful error messages when tests fail to run, such as "too many open files". This change checks for more filesystem related errors and calls t.Fatal if there is an error.
211 lines
5.7 KiB
Go
211 lines
5.7 KiB
Go
// Copyright 2018-2019 The NATS Authors
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/nats-io/nats-server/v2/server"
|
|
)
|
|
|
|
// waits until a calculated list of listeners is resolved or a timeout
|
|
func waitForFile(path string, dur time.Duration) ([]byte, error) {
|
|
end := time.Now().Add(dur)
|
|
for time.Now().Before(end) {
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
time.Sleep(25 * time.Millisecond)
|
|
continue
|
|
} else {
|
|
return ioutil.ReadFile(path)
|
|
}
|
|
}
|
|
return nil, errors.New("Timeout")
|
|
}
|
|
|
|
func portFile(dirname string) string {
|
|
return filepath.Join(dirname, fmt.Sprintf("%s_%d.ports", filepath.Base(os.Args[0]), os.Getpid()))
|
|
}
|
|
|
|
func TestPortsFile(t *testing.T) {
|
|
portFileDir := createDir(t, "")
|
|
|
|
opts := DefaultTestOptions
|
|
opts.PortsFileDir = portFileDir
|
|
opts.Port = -1
|
|
opts.HTTPPort = -1
|
|
opts.ProfPort = -1
|
|
opts.Cluster.Port = -1
|
|
opts.Websocket.Port = -1
|
|
tc := &server.TLSConfigOpts{
|
|
CertFile: "./configs/certs/server-cert.pem",
|
|
KeyFile: "./configs/certs/server-key.pem",
|
|
}
|
|
opts.Websocket.TLSConfig, _ = server.GenTLSConfig(tc)
|
|
|
|
s := RunServer(&opts)
|
|
// this for test cleanup in case we fail - will be ignored if server already shutdown
|
|
defer s.Shutdown()
|
|
|
|
ports := s.PortsInfo(5 * time.Second)
|
|
|
|
if ports == nil {
|
|
t.Fatal("services failed to start in 5 seconds")
|
|
}
|
|
|
|
// the pid file should be
|
|
portsFile := portFile(portFileDir)
|
|
|
|
if portsFile == "" {
|
|
t.Fatal("Expected a ports file")
|
|
}
|
|
|
|
// try to read a file here - the file should be a json
|
|
buf, err := waitForFile(portsFile, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("Could not read ports file: %v", err)
|
|
}
|
|
if len(buf) <= 0 {
|
|
t.Fatal("Expected a non-zero length ports file")
|
|
}
|
|
|
|
readPorts := server.Ports{}
|
|
json.Unmarshal(buf, &readPorts)
|
|
|
|
if len(readPorts.Nats) == 0 || !strings.HasPrefix(readPorts.Nats[0], "nats://") {
|
|
t.Fatal("Expected at least one nats url")
|
|
}
|
|
|
|
if len(readPorts.Monitoring) == 0 || !strings.HasPrefix(readPorts.Monitoring[0], "http://") {
|
|
t.Fatal("Expected at least one monitoring url")
|
|
}
|
|
|
|
if len(readPorts.Cluster) == 0 || !strings.HasPrefix(readPorts.Cluster[0], "nats://") {
|
|
t.Fatal("Expected at least one cluster listen url")
|
|
}
|
|
|
|
if len(readPorts.Profile) == 0 || !strings.HasPrefix(readPorts.Profile[0], "http://") {
|
|
t.Fatal("Expected at least one profile listen url")
|
|
}
|
|
|
|
if len(readPorts.WebSocket) == 0 || !strings.HasPrefix(readPorts.WebSocket[0], "wss://") {
|
|
t.Fatal("Expected at least one ws listen url")
|
|
}
|
|
|
|
// testing cleanup
|
|
s.Shutdown()
|
|
// if we called shutdown, the cleanup code should have kicked
|
|
if _, err := os.Stat(portsFile); os.IsNotExist(err) {
|
|
// good
|
|
} else {
|
|
t.Fatalf("the port file %s was not deleted", portsFile)
|
|
}
|
|
}
|
|
|
|
// makes a temp directory with two directories 'A' and 'B'
|
|
// the location of the ports file is changed from dir A to dir B.
|
|
func TestPortsFileReload(t *testing.T) {
|
|
// make a temp dir
|
|
tempDir := createDir(t, "")
|
|
defer removeDir(t, tempDir)
|
|
|
|
// make child temp dir A
|
|
dirA := filepath.Join(tempDir, "A")
|
|
os.MkdirAll(dirA, 0777)
|
|
|
|
// write the config file with a reference to A
|
|
config := fmt.Sprintf(`
|
|
ports_file_dir: "%s"
|
|
port: -1
|
|
`, dirA)
|
|
config = strings.Replace(config, "\\", "/", -1)
|
|
confPath := filepath.Join(tempDir, fmt.Sprintf("%d.conf", os.Getpid()))
|
|
if err := ioutil.WriteFile(confPath, []byte(config), 0666); err != nil {
|
|
t.Fatalf("Error writing ports file (%s): %v", confPath, err)
|
|
}
|
|
|
|
opts, err := server.ProcessConfigFile(confPath)
|
|
if err != nil {
|
|
t.Fatalf("Error processing the configuration: %v", err)
|
|
}
|
|
|
|
s := RunServer(opts)
|
|
defer s.Shutdown()
|
|
|
|
ports := s.PortsInfo(5 * time.Second)
|
|
if ports == nil {
|
|
t.Fatal("services failed to start in 5 seconds")
|
|
}
|
|
|
|
// get the ports file path name
|
|
portsFileInA := portFile(dirA)
|
|
// the file should be in dirA
|
|
if !strings.HasPrefix(portsFileInA, dirA) {
|
|
t.Fatalf("expected ports file to be in [%s] but was in [%s]", dirA, portsFileInA)
|
|
}
|
|
// wait for it
|
|
buf, err := waitForFile(portsFileInA, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("Could not read ports file: %v", err)
|
|
}
|
|
if len(buf) <= 0 {
|
|
t.Fatal("Expected a non-zero length ports file")
|
|
}
|
|
|
|
// change the configuration for the ports file to dirB
|
|
dirB := filepath.Join(tempDir, "B")
|
|
os.MkdirAll(dirB, 0777)
|
|
|
|
config = fmt.Sprintf(`
|
|
ports_file_dir: "%s"
|
|
port: -1
|
|
`, dirB)
|
|
config = strings.Replace(config, "\\", "/", -1)
|
|
if err := ioutil.WriteFile(confPath, []byte(config), 0666); err != nil {
|
|
t.Fatalf("Error writing ports file (%s): %v", confPath, err)
|
|
}
|
|
|
|
// reload the server
|
|
if err := s.Reload(); err != nil {
|
|
t.Fatalf("error reloading server: %v", err)
|
|
}
|
|
|
|
// wait for the new file to show up
|
|
portsFileInB := portFile(dirB)
|
|
buf, err = waitForFile(portsFileInB, 5*time.Second)
|
|
if !strings.HasPrefix(portsFileInB, dirB) {
|
|
t.Fatalf("expected ports file to be in [%s] but was in [%s]", dirB, portsFileInB)
|
|
}
|
|
if err != nil {
|
|
t.Fatalf("Could not read ports file: %v", err)
|
|
}
|
|
if len(buf) <= 0 {
|
|
t.Fatal("Expected a non-zero length ports file")
|
|
}
|
|
|
|
// the file in dirA should have deleted
|
|
if _, err := os.Stat(portsFileInA); os.IsNotExist(err) {
|
|
// good
|
|
} else {
|
|
t.Fatalf("the port file %s was not deleted", portsFileInA)
|
|
}
|
|
}
|