github.com/mongey/nomad@v0.5.2/command/agent/agent_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net"
     7  	"os"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/hashicorp/nomad/nomad"
    13  	sconfig "github.com/hashicorp/nomad/nomad/structs/config"
    14  )
    15  
    16  func getPort() int {
    17  	addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
    18  	if err != nil {
    19  		panic(err)
    20  	}
    21  
    22  	l, err := net.ListenTCP("tcp", addr)
    23  	if err != nil {
    24  		panic(err)
    25  	}
    26  	defer l.Close()
    27  	return l.Addr().(*net.TCPAddr).Port
    28  }
    29  
    30  func tmpDir(t testing.TB) string {
    31  	dir, err := ioutil.TempDir("", "nomad")
    32  	if err != nil {
    33  		t.Fatalf("err: %v", err)
    34  	}
    35  	return dir
    36  }
    37  
    38  func makeAgent(t testing.TB, cb func(*Config)) (string, *Agent) {
    39  	dir := tmpDir(t)
    40  	conf := DevConfig()
    41  
    42  	// Customize the server configuration
    43  	config := nomad.DefaultConfig()
    44  	conf.NomadConfig = config
    45  
    46  	// Set the data_dir
    47  	conf.DataDir = dir
    48  	conf.NomadConfig.DataDir = dir
    49  
    50  	// Bind and set ports
    51  	conf.BindAddr = "127.0.0.1"
    52  	conf.Ports = &Ports{
    53  		HTTP: getPort(),
    54  		RPC:  getPort(),
    55  		Serf: getPort(),
    56  	}
    57  	conf.NodeName = fmt.Sprintf("Node %d", conf.Ports.RPC)
    58  	conf.Consul = sconfig.DefaultConsulConfig()
    59  	conf.Vault.Enabled = new(bool)
    60  
    61  	// Tighten the Serf timing
    62  	config.SerfConfig.MemberlistConfig.SuspicionMult = 2
    63  	config.SerfConfig.MemberlistConfig.RetransmitMult = 2
    64  	config.SerfConfig.MemberlistConfig.ProbeTimeout = 50 * time.Millisecond
    65  	config.SerfConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
    66  	config.SerfConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond
    67  
    68  	// Tighten the Raft timing
    69  	config.RaftConfig.LeaderLeaseTimeout = 20 * time.Millisecond
    70  	config.RaftConfig.HeartbeatTimeout = 40 * time.Millisecond
    71  	config.RaftConfig.ElectionTimeout = 40 * time.Millisecond
    72  	config.RaftConfig.StartAsLeader = true
    73  	config.RaftTimeout = 500 * time.Millisecond
    74  
    75  	if cb != nil {
    76  		cb(conf)
    77  	}
    78  
    79  	if err := conf.normalizeAddrs(); err != nil {
    80  		t.Fatalf("error normalizing config: %v", err)
    81  	}
    82  	agent, err := NewAgent(conf, os.Stderr)
    83  	if err != nil {
    84  		os.RemoveAll(dir)
    85  		t.Fatalf("err: %v", err)
    86  	}
    87  	return dir, agent
    88  }
    89  
    90  func TestAgent_RPCPing(t *testing.T) {
    91  	dir, agent := makeAgent(t, nil)
    92  	defer os.RemoveAll(dir)
    93  	defer agent.Shutdown()
    94  
    95  	var out struct{}
    96  	if err := agent.RPC("Status.Ping", struct{}{}, &out); err != nil {
    97  		t.Fatalf("err: %v", err)
    98  	}
    99  }
   100  
   101  func TestAgent_ServerConfig(t *testing.T) {
   102  	conf := DefaultConfig()
   103  	conf.DevMode = true // allow localhost for advertise addrs
   104  	a := &Agent{config: conf}
   105  
   106  	conf.AdvertiseAddrs.Serf = "127.0.0.1:4000"
   107  	conf.AdvertiseAddrs.RPC = "127.0.0.1:4001"
   108  	conf.AdvertiseAddrs.HTTP = "10.10.11.1:4005"
   109  
   110  	// Parses the advertise addrs correctly
   111  	if err := conf.normalizeAddrs(); err != nil {
   112  		t.Fatalf("error normalizing config: %v", err)
   113  	}
   114  	out, err := a.serverConfig()
   115  	if err != nil {
   116  		t.Fatalf("err: %s", err)
   117  	}
   118  	serfAddr := out.SerfConfig.MemberlistConfig.AdvertiseAddr
   119  	if serfAddr != "127.0.0.1" {
   120  		t.Fatalf("expect 127.0.0.1, got: %s", serfAddr)
   121  	}
   122  	serfPort := out.SerfConfig.MemberlistConfig.AdvertisePort
   123  	if serfPort != 4000 {
   124  		t.Fatalf("expected 4000, got: %d", serfPort)
   125  	}
   126  
   127  	// Assert addresses weren't changed
   128  	if addr := conf.AdvertiseAddrs.RPC; addr != "127.0.0.1:4001" {
   129  		t.Fatalf("bad rpc advertise addr: %#v", addr)
   130  	}
   131  	if addr := conf.AdvertiseAddrs.HTTP; addr != "10.10.11.1:4005" {
   132  		t.Fatalf("expect 10.11.11.1:4005, got: %v", addr)
   133  	}
   134  	if addr := conf.Addresses.RPC; addr != "0.0.0.0" {
   135  		t.Fatalf("expect 0.0.0.0, got: %v", addr)
   136  	}
   137  
   138  	// Sets up the ports properly
   139  	conf.Addresses.RPC = ""
   140  	conf.Addresses.Serf = ""
   141  	conf.Ports.RPC = 4003
   142  	conf.Ports.Serf = 4004
   143  
   144  	if err := conf.normalizeAddrs(); err != nil {
   145  		t.Fatalf("error normalizing config: %v", err)
   146  	}
   147  	out, err = a.serverConfig()
   148  	if err != nil {
   149  		t.Fatalf("err: %s", err)
   150  	}
   151  	if addr := out.RPCAddr.Port; addr != 4003 {
   152  		t.Fatalf("expect 4003, got: %d", out.RPCAddr.Port)
   153  	}
   154  	if port := out.SerfConfig.MemberlistConfig.BindPort; port != 4004 {
   155  		t.Fatalf("expect 4004, got: %d", port)
   156  	}
   157  
   158  	// Prefers advertise over bind addr
   159  	conf.BindAddr = "127.0.0.3"
   160  	conf.Addresses.HTTP = "127.0.0.2"
   161  	conf.Addresses.RPC = "127.0.0.2"
   162  	conf.Addresses.Serf = "127.0.0.2"
   163  	conf.AdvertiseAddrs.HTTP = "10.0.0.10"
   164  	conf.AdvertiseAddrs.RPC = ""
   165  	conf.AdvertiseAddrs.Serf = "10.0.0.12:4004"
   166  
   167  	if err := conf.normalizeAddrs(); err != nil {
   168  		t.Fatalf("error normalizing config: %v", err)
   169  	}
   170  	out, err = a.serverConfig()
   171  	fmt.Println(conf.Addresses.RPC)
   172  	if err != nil {
   173  		t.Fatalf("err: %s", err)
   174  	}
   175  	if addr := out.RPCAddr.IP.String(); addr != "127.0.0.2" {
   176  		t.Fatalf("expect 127.0.0.2, got: %s", addr)
   177  	}
   178  	if port := out.RPCAddr.Port; port != 4003 {
   179  		t.Fatalf("expect 4647, got: %d", port)
   180  	}
   181  	if addr := out.SerfConfig.MemberlistConfig.BindAddr; addr != "127.0.0.2" {
   182  		t.Fatalf("expect 127.0.0.2, got: %s", addr)
   183  	}
   184  	if port := out.SerfConfig.MemberlistConfig.BindPort; port != 4004 {
   185  		t.Fatalf("expect 4648, got: %d", port)
   186  	}
   187  	if addr := conf.Addresses.HTTP; addr != "127.0.0.2" {
   188  		t.Fatalf("expect 127.0.0.2, got: %s", addr)
   189  	}
   190  	if addr := conf.Addresses.RPC; addr != "127.0.0.2" {
   191  		t.Fatalf("expect 127.0.0.2, got: %s", addr)
   192  	}
   193  	if addr := conf.Addresses.Serf; addr != "127.0.0.2" {
   194  		t.Fatalf("expect 10.0.0.12, got: %s", addr)
   195  	}
   196  	if addr := conf.normalizedAddrs.HTTP; addr != "127.0.0.2:4646" {
   197  		t.Fatalf("expect 127.0.0.2:4646, got: %s", addr)
   198  	}
   199  	if addr := conf.normalizedAddrs.RPC; addr != "127.0.0.2:4003" {
   200  		t.Fatalf("expect 127.0.0.2:4003, got: %s", addr)
   201  	}
   202  	if addr := conf.normalizedAddrs.Serf; addr != "127.0.0.2:4004" {
   203  		t.Fatalf("expect 10.0.0.12:4004, got: %s", addr)
   204  	}
   205  	if addr := conf.AdvertiseAddrs.HTTP; addr != "10.0.0.10:4646" {
   206  		t.Fatalf("expect 10.0.0.10:4646, got: %s", addr)
   207  	}
   208  	if addr := conf.AdvertiseAddrs.RPC; addr != "127.0.0.2:4003" {
   209  		t.Fatalf("expect 127.0.0.2:4003, got: %s", addr)
   210  	}
   211  	if addr := conf.AdvertiseAddrs.Serf; addr != "10.0.0.12:4004" {
   212  		t.Fatalf("expect 10.0.0.12:4004, got: %s", addr)
   213  	}
   214  
   215  	conf.Server.NodeGCThreshold = "42g"
   216  	if err := conf.normalizeAddrs(); err != nil {
   217  		t.Fatalf("error normalizing config: %v", err)
   218  	}
   219  	out, err = a.serverConfig()
   220  	if err == nil || !strings.Contains(err.Error(), "unknown unit") {
   221  		t.Fatalf("expected unknown unit error, got: %#v", err)
   222  	}
   223  
   224  	conf.Server.NodeGCThreshold = "10s"
   225  	if err := conf.normalizeAddrs(); err != nil {
   226  		t.Fatalf("error normalizing config: %v", err)
   227  	}
   228  	out, err = a.serverConfig()
   229  	if threshold := out.NodeGCThreshold; threshold != time.Second*10 {
   230  		t.Fatalf("expect 10s, got: %s", threshold)
   231  	}
   232  
   233  	conf.Server.HeartbeatGrace = "42g"
   234  	if err := conf.normalizeAddrs(); err != nil {
   235  		t.Fatalf("error normalizing config: %v", err)
   236  	}
   237  	out, err = a.serverConfig()
   238  	if err == nil || !strings.Contains(err.Error(), "unknown unit") {
   239  		t.Fatalf("expected unknown unit error, got: %#v", err)
   240  	}
   241  
   242  	conf.Server.HeartbeatGrace = "37s"
   243  	if err := conf.normalizeAddrs(); err != nil {
   244  		t.Fatalf("error normalizing config: %v", err)
   245  	}
   246  	out, err = a.serverConfig()
   247  	if threshold := out.HeartbeatGrace; threshold != time.Second*37 {
   248  		t.Fatalf("expect 37s, got: %s", threshold)
   249  	}
   250  
   251  	// Defaults to the global bind addr
   252  	conf.Addresses.RPC = ""
   253  	conf.Addresses.Serf = ""
   254  	conf.Addresses.HTTP = ""
   255  	conf.AdvertiseAddrs.RPC = ""
   256  	conf.AdvertiseAddrs.HTTP = ""
   257  	conf.AdvertiseAddrs.Serf = ""
   258  	conf.Ports.HTTP = 4646
   259  	conf.Ports.RPC = 4647
   260  	conf.Ports.Serf = 4648
   261  	if err := conf.normalizeAddrs(); err != nil {
   262  		t.Fatalf("error normalizing config: %v", err)
   263  	}
   264  	out, err = a.serverConfig()
   265  	if err != nil {
   266  		t.Fatalf("err: %s", err)
   267  	}
   268  	if addr := out.RPCAddr.IP.String(); addr != "127.0.0.3" {
   269  		t.Fatalf("expect 127.0.0.3, got: %s", addr)
   270  	}
   271  	if addr := out.SerfConfig.MemberlistConfig.BindAddr; addr != "127.0.0.3" {
   272  		t.Fatalf("expect 127.0.0.3, got: %s", addr)
   273  	}
   274  	if addr := conf.Addresses.HTTP; addr != "127.0.0.3" {
   275  		t.Fatalf("expect 127.0.0.3, got: %s", addr)
   276  	}
   277  	if addr := conf.Addresses.RPC; addr != "127.0.0.3" {
   278  		t.Fatalf("expect 127.0.0.3, got: %s", addr)
   279  	}
   280  	if addr := conf.Addresses.Serf; addr != "127.0.0.3" {
   281  		t.Fatalf("expect 127.0.0.3, got: %s", addr)
   282  	}
   283  	if addr := conf.normalizedAddrs.HTTP; addr != "127.0.0.3:4646" {
   284  		t.Fatalf("expect 127.0.0.3:4646, got: %s", addr)
   285  	}
   286  	if addr := conf.normalizedAddrs.RPC; addr != "127.0.0.3:4647" {
   287  		t.Fatalf("expect 127.0.0.3:4647, got: %s", addr)
   288  	}
   289  	if addr := conf.normalizedAddrs.Serf; addr != "127.0.0.3:4648" {
   290  		t.Fatalf("expect 127.0.0.3:4648, got: %s", addr)
   291  	}
   292  
   293  	// Properly handles the bootstrap flags
   294  	conf.Server.BootstrapExpect = 1
   295  	out, err = a.serverConfig()
   296  	if err != nil {
   297  		t.Fatalf("err: %s", err)
   298  	}
   299  	if !out.Bootstrap {
   300  		t.Fatalf("should have set bootstrap mode")
   301  	}
   302  	if out.BootstrapExpect != 0 {
   303  		t.Fatalf("boostrap expect should be 0")
   304  	}
   305  
   306  	conf.Server.BootstrapExpect = 3
   307  	out, err = a.serverConfig()
   308  	if err != nil {
   309  		t.Fatalf("err: %s", err)
   310  	}
   311  	if out.Bootstrap {
   312  		t.Fatalf("bootstrap mode should be disabled")
   313  	}
   314  	if out.BootstrapExpect != 3 {
   315  		t.Fatalf("should have bootstrap-expect = 3")
   316  	}
   317  }
   318  
   319  func TestAgent_ClientConfig(t *testing.T) {
   320  	conf := DefaultConfig()
   321  	conf.Client.Enabled = true
   322  
   323  	// For Clients HTTP and RPC must be set (Serf can be skipped)
   324  	conf.Addresses.HTTP = "169.254.0.1"
   325  	conf.Addresses.RPC = "169.254.0.1"
   326  	conf.Ports.HTTP = 5678
   327  	a := &Agent{config: conf}
   328  
   329  	if err := conf.normalizeAddrs(); err != nil {
   330  		t.Fatalf("error normalizing config: %v", err)
   331  	}
   332  	c, err := a.clientConfig()
   333  	if err != nil {
   334  		t.Fatalf("got err: %v", err)
   335  	}
   336  
   337  	expectedHttpAddr := "169.254.0.1:5678"
   338  	if c.Node.HTTPAddr != expectedHttpAddr {
   339  		t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
   340  	}
   341  
   342  	conf = DefaultConfig()
   343  	conf.DevMode = true
   344  	a = &Agent{config: conf}
   345  	conf.Client.Enabled = true
   346  	conf.Addresses.HTTP = "169.254.0.1"
   347  
   348  	if err := conf.normalizeAddrs(); err != nil {
   349  		t.Fatalf("error normalizing config: %v", err)
   350  	}
   351  	c, err = a.clientConfig()
   352  	if err != nil {
   353  		t.Fatalf("got err: %v", err)
   354  	}
   355  
   356  	expectedHttpAddr = "169.254.0.1:4646"
   357  	if c.Node.HTTPAddr != expectedHttpAddr {
   358  		t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
   359  	}
   360  }