2015-09-10 04:42:50 +00:00
|
|
|
package agent
|
|
|
|
|
|
|
|
import (
|
2015-09-10 05:11:48 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2015-09-10 04:42:50 +00:00
|
|
|
"reflect"
|
|
|
|
"testing"
|
2015-09-10 18:24:59 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
2015-09-10 04:42:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestConfig_Merge(t *testing.T) {
|
|
|
|
c1 := &Config{
|
2015-09-14 01:18:40 +00:00
|
|
|
Region: "global",
|
2015-09-10 04:42:50 +00:00
|
|
|
Datacenter: "dc1",
|
|
|
|
NodeName: "node1",
|
|
|
|
DataDir: "/tmp/dir1",
|
|
|
|
LogLevel: "INFO",
|
|
|
|
EnableDebug: false,
|
|
|
|
LeaveOnInt: false,
|
|
|
|
LeaveOnTerm: false,
|
|
|
|
EnableSyslog: false,
|
|
|
|
SyslogFacility: "local0.info",
|
|
|
|
DisableUpdateCheck: false,
|
|
|
|
DisableAnonymousSignature: false,
|
2015-09-11 02:04:06 +00:00
|
|
|
BindAddr: "127.0.0.1",
|
2015-09-10 18:24:59 +00:00
|
|
|
Telemetry: &Telemetry{
|
|
|
|
StatsiteAddr: "127.0.0.1:8125",
|
|
|
|
StatsdAddr: "127.0.0.1:8125",
|
|
|
|
DisableHostname: false,
|
|
|
|
},
|
|
|
|
Client: &ClientConfig{
|
|
|
|
Enabled: false,
|
|
|
|
StateDir: "/tmp/state1",
|
|
|
|
AllocDir: "/tmp/alloc1",
|
|
|
|
NodeID: "node1",
|
|
|
|
NodeClass: "class1",
|
|
|
|
},
|
|
|
|
Server: &ServerConfig{
|
|
|
|
Enabled: false,
|
|
|
|
Bootstrap: false,
|
|
|
|
BootstrapExpect: 1,
|
|
|
|
DataDir: "/tmp/data1",
|
|
|
|
ProtocolVersion: 1,
|
|
|
|
NumSchedulers: 1,
|
|
|
|
},
|
2015-09-11 02:04:06 +00:00
|
|
|
Ports: &Ports{
|
|
|
|
HTTP: 4646,
|
|
|
|
RPC: 4647,
|
|
|
|
Serf: 4648,
|
|
|
|
},
|
|
|
|
Addresses: &Addresses{
|
|
|
|
HTTP: "127.0.0.1",
|
|
|
|
RPC: "127.0.0.1",
|
|
|
|
Serf: "127.0.0.1",
|
|
|
|
},
|
|
|
|
AdvertiseAddrs: &AdvertiseAddrs{
|
|
|
|
RPC: "127.0.0.1",
|
|
|
|
Serf: "127.0.0.1",
|
|
|
|
},
|
2015-09-10 04:42:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
c2 := &Config{
|
|
|
|
Region: "region2",
|
|
|
|
Datacenter: "dc2",
|
|
|
|
NodeName: "node2",
|
|
|
|
DataDir: "/tmp/dir2",
|
|
|
|
LogLevel: "DEBUG",
|
|
|
|
EnableDebug: true,
|
|
|
|
LeaveOnInt: true,
|
|
|
|
LeaveOnTerm: true,
|
|
|
|
EnableSyslog: true,
|
|
|
|
SyslogFacility: "local0.debug",
|
|
|
|
DisableUpdateCheck: true,
|
|
|
|
DisableAnonymousSignature: true,
|
2015-09-11 02:04:06 +00:00
|
|
|
BindAddr: "127.0.0.2",
|
2015-09-10 18:24:59 +00:00
|
|
|
Telemetry: &Telemetry{
|
|
|
|
StatsiteAddr: "127.0.0.2:8125",
|
|
|
|
StatsdAddr: "127.0.0.2:8125",
|
|
|
|
DisableHostname: true,
|
|
|
|
},
|
|
|
|
Client: &ClientConfig{
|
|
|
|
Enabled: true,
|
|
|
|
StateDir: "/tmp/state2",
|
|
|
|
AllocDir: "/tmp/alloc2",
|
|
|
|
NodeID: "node2",
|
|
|
|
NodeClass: "class2",
|
|
|
|
Servers: []string{"server2"},
|
|
|
|
Meta: map[string]string{"baz": "zip"},
|
|
|
|
},
|
|
|
|
Server: &ServerConfig{
|
|
|
|
Enabled: true,
|
|
|
|
Bootstrap: true,
|
|
|
|
BootstrapExpect: 2,
|
|
|
|
DataDir: "/tmp/data2",
|
|
|
|
ProtocolVersion: 2,
|
|
|
|
NumSchedulers: 2,
|
|
|
|
EnabledSchedulers: []string{structs.JobTypeBatch},
|
|
|
|
},
|
2015-09-11 02:04:06 +00:00
|
|
|
Ports: &Ports{
|
|
|
|
HTTP: 20000,
|
|
|
|
RPC: 21000,
|
|
|
|
Serf: 22000,
|
|
|
|
},
|
|
|
|
Addresses: &Addresses{
|
|
|
|
HTTP: "127.0.0.2",
|
|
|
|
RPC: "127.0.0.2",
|
|
|
|
Serf: "127.0.0.2",
|
|
|
|
},
|
|
|
|
AdvertiseAddrs: &AdvertiseAddrs{
|
|
|
|
RPC: "127.0.0.2",
|
|
|
|
Serf: "127.0.0.2",
|
|
|
|
},
|
2015-09-10 04:42:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
result := c1.Merge(c2)
|
|
|
|
if !reflect.DeepEqual(result, c2) {
|
2015-09-10 18:24:59 +00:00
|
|
|
t.Fatalf("bad:\n%#v\n%#v", result.Server, c2.Server)
|
2015-09-10 04:42:50 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-10 05:11:48 +00:00
|
|
|
|
|
|
|
func TestConfig_LoadConfigFile(t *testing.T) {
|
|
|
|
// Fails if the file doesn't exist
|
|
|
|
if _, err := LoadConfigFile("/unicorns/leprechauns"); err == nil {
|
|
|
|
t.Fatalf("expected error, got nothing")
|
|
|
|
}
|
|
|
|
|
|
|
|
fh, err := ioutil.TempFile("", "nomad")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(fh.Name())
|
|
|
|
|
|
|
|
// Invalid content returns error
|
|
|
|
if _, err := fh.WriteString("nope"); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if _, err := LoadConfigFile(fh.Name()); err == nil {
|
|
|
|
t.Fatalf("expected load error, got nothing")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Valid content parses successfully
|
|
|
|
if err := fh.Truncate(0); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if _, err := fh.Seek(0, 0); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if _, err := fh.WriteString(`{"region":"west"}`); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
config, err := LoadConfigFile(fh.Name())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if config.Region != "west" {
|
|
|
|
t.Fatalf("bad region: %q", config.Region)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestConfig_LoadConfigDir(t *testing.T) {
|
|
|
|
// Fails if the dir doesn't exist.
|
|
|
|
if _, err := LoadConfigDir("/unicorns/leprechauns"); err == nil {
|
|
|
|
t.Fatalf("expected error, got nothing")
|
|
|
|
}
|
|
|
|
|
|
|
|
dir, err := ioutil.TempDir("", "nomad")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(dir)
|
|
|
|
|
|
|
|
file1 := filepath.Join(dir, "conf1.hcl")
|
|
|
|
err = ioutil.WriteFile(file1, []byte(`{"region":"west"}`), 0600)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
file2 := filepath.Join(dir, "conf2.hcl")
|
|
|
|
err = ioutil.WriteFile(file2, []byte(`{"datacenter":"sfo"}`), 0600)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
file3 := filepath.Join(dir, "conf3.hcl")
|
|
|
|
err = ioutil.WriteFile(file3, []byte(`nope`), 0600)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fails if we have a bad config file
|
|
|
|
if _, err := LoadConfigDir(dir); err == nil {
|
|
|
|
t.Fatalf("expected load error, got nothing")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.Remove(file3); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Works if configs are valid
|
|
|
|
config, err := LoadConfigDir(dir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if config.Region != "west" || config.Datacenter != "sfo" {
|
|
|
|
t.Fatalf("bad: %#v", config)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestConfig_LoadConfig(t *testing.T) {
|
|
|
|
// Fails if the target doesn't exist
|
|
|
|
if _, err := LoadConfig("/unicorns/leprechauns"); err == nil {
|
|
|
|
t.Fatalf("expected error, got nothing")
|
|
|
|
}
|
|
|
|
|
|
|
|
fh, err := ioutil.TempFile("", "nomad")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(fh.Name())
|
|
|
|
|
|
|
|
if _, err := fh.WriteString(`{"region":"west"}`); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Works on a config file
|
|
|
|
config, err := LoadConfig(fh.Name())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if config.Region != "west" {
|
|
|
|
t.Fatalf("bad: %#v", config)
|
|
|
|
}
|
|
|
|
|
|
|
|
dir, err := ioutil.TempDir("", "nomad")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(dir)
|
|
|
|
|
|
|
|
file1 := filepath.Join(dir, "config1.hcl")
|
|
|
|
err = ioutil.WriteFile(file1, []byte(`{"datacenter":"sfo"}`), 0600)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Works on config dir
|
|
|
|
config, err = LoadConfig(dir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
if config.Datacenter != "sfo" {
|
|
|
|
t.Fatalf("bad: %#v", config)
|
|
|
|
}
|
|
|
|
}
|
2015-09-11 02:15:17 +00:00
|
|
|
|
|
|
|
func TestConfig_Listener(t *testing.T) {
|
|
|
|
config := DefaultConfig()
|
|
|
|
|
|
|
|
// Fails on invalid input
|
|
|
|
if _, err := config.Listener("tcp", "nope", 8080); err == nil {
|
|
|
|
t.Fatalf("expected addr error")
|
|
|
|
}
|
|
|
|
if _, err := config.Listener("nope", "127.0.0.1", 8080); err == nil {
|
|
|
|
t.Fatalf("expected protocol err")
|
|
|
|
}
|
|
|
|
if _, err := config.Listener("tcp", "127.0.0.1", -1); err == nil {
|
|
|
|
t.Fatalf("expected port error")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Works with valid inputs
|
|
|
|
ln, err := config.Listener("tcp", "127.0.0.1", 24000)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
ln.Close()
|
|
|
|
|
|
|
|
if net := ln.Addr().Network(); net != "tcp" {
|
|
|
|
t.Fatalf("expected tcp, got: %q", net)
|
|
|
|
}
|
|
|
|
if addr := ln.Addr().String(); addr != "127.0.0.1:24000" {
|
|
|
|
t.Fatalf("expected 127.0.0.1:4646, got: %q", addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Falls back to default bind address if non provided
|
|
|
|
config.BindAddr = "0.0.0.0"
|
|
|
|
ln, err = config.Listener("tcp4", "", 24000)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
ln.Close()
|
|
|
|
|
|
|
|
if addr := ln.Addr().String(); addr != "0.0.0.0:24000" {
|
|
|
|
t.Fatalf("expected 0.0.0.0:24000, got: %q", addr)
|
|
|
|
}
|
|
|
|
}
|