github.com/taylorchu/nomad@v0.5.3-rc1.0.20170407200202-db11e7dd7b55/nomad/server_test.go (about)

     1  package nomad
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"log"
     7  	"net"
     8  	"sync/atomic"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/hashicorp/nomad/command/agent/consul"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/nomad/structs/config"
    15  	"github.com/hashicorp/nomad/testutil"
    16  )
    17  
    18  var (
    19  	nextPort   uint32 = 15000
    20  	nodeNumber uint32 = 0
    21  )
    22  
    23  func getPort() int {
    24  	return int(atomic.AddUint32(&nextPort, 1))
    25  }
    26  
    27  func tmpDir(t *testing.T) string {
    28  	dir, err := ioutil.TempDir("", "nomad")
    29  	if err != nil {
    30  		t.Fatalf("err: %v", err)
    31  	}
    32  	return dir
    33  }
    34  
    35  func testServer(t *testing.T, cb func(*Config)) *Server {
    36  	// Setup the default settings
    37  	config := DefaultConfig()
    38  	config.Build = "unittest"
    39  	config.DevMode = true
    40  	config.RPCAddr = &net.TCPAddr{
    41  		IP:   []byte{127, 0, 0, 1},
    42  		Port: getPort(),
    43  	}
    44  	nodeNum := atomic.AddUint32(&nodeNumber, 1)
    45  	config.NodeName = fmt.Sprintf("nomad-%03d", nodeNum)
    46  
    47  	// Tighten the Serf timing
    48  	config.SerfConfig.MemberlistConfig.BindAddr = "127.0.0.1"
    49  	config.SerfConfig.MemberlistConfig.BindPort = getPort()
    50  	config.SerfConfig.MemberlistConfig.SuspicionMult = 2
    51  	config.SerfConfig.MemberlistConfig.RetransmitMult = 2
    52  	config.SerfConfig.MemberlistConfig.ProbeTimeout = 50 * time.Millisecond
    53  	config.SerfConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
    54  	config.SerfConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond
    55  
    56  	// Tighten the Raft timing
    57  	config.RaftConfig.LeaderLeaseTimeout = 50 * time.Millisecond
    58  	config.RaftConfig.HeartbeatTimeout = 50 * time.Millisecond
    59  	config.RaftConfig.ElectionTimeout = 50 * time.Millisecond
    60  	config.RaftTimeout = 500 * time.Millisecond
    61  
    62  	// Disable Vault
    63  	f := false
    64  	config.VaultConfig.Enabled = &f
    65  
    66  	// Squelch output when -v isn't specified
    67  	if !testing.Verbose() {
    68  		config.LogOutput = ioutil.Discard
    69  	}
    70  
    71  	// Invoke the callback if any
    72  	if cb != nil {
    73  		cb(config)
    74  	}
    75  
    76  	// Enable raft as leader if we have bootstrap on
    77  	config.RaftConfig.StartAsLeader = !config.DevDisableBootstrap
    78  
    79  	shutdownCh := make(chan struct{})
    80  	logger := log.New(config.LogOutput, fmt.Sprintf("[%s] ", config.NodeName), log.LstdFlags)
    81  	consulSyncer, err := consul.NewSyncer(config.ConsulConfig, shutdownCh, logger)
    82  	if err != nil {
    83  		t.Fatalf("err: %v", err)
    84  	}
    85  
    86  	// Create server
    87  	server, err := NewServer(config, consulSyncer, logger)
    88  	if err != nil {
    89  		t.Fatalf("err: %v", err)
    90  	}
    91  	return server
    92  }
    93  
    94  func testJoin(t *testing.T, s1 *Server, other ...*Server) {
    95  	addr := fmt.Sprintf("127.0.0.1:%d",
    96  		s1.config.SerfConfig.MemberlistConfig.BindPort)
    97  	for _, s2 := range other {
    98  		if num, err := s2.Join([]string{addr}); err != nil {
    99  			t.Fatalf("err: %v", err)
   100  		} else if num != 1 {
   101  			t.Fatalf("bad: %d", num)
   102  		}
   103  	}
   104  }
   105  
   106  func TestServer_RPC(t *testing.T) {
   107  	s1 := testServer(t, nil)
   108  	defer s1.Shutdown()
   109  
   110  	var out struct{}
   111  	if err := s1.RPC("Status.Ping", struct{}{}, &out); err != nil {
   112  		t.Fatalf("err: %v", err)
   113  	}
   114  }
   115  
   116  func TestServer_RPC_MixedTLS(t *testing.T) {
   117  	const (
   118  		cafile  = "../helper/tlsutil/testdata/ca.pem"
   119  		foocert = "../helper/tlsutil/testdata/nomad-foo.pem"
   120  		fookey  = "../helper/tlsutil/testdata/nomad-foo-key.pem"
   121  	)
   122  	s1 := testServer(t, func(c *Config) {
   123  		c.BootstrapExpect = 3
   124  		c.DevDisableBootstrap = true
   125  		c.TLSConfig = &config.TLSConfig{
   126  			EnableHTTP:           true,
   127  			EnableRPC:            true,
   128  			VerifyServerHostname: true,
   129  			CAFile:               cafile,
   130  			CertFile:             foocert,
   131  			KeyFile:              fookey,
   132  		}
   133  	})
   134  	defer s1.Shutdown()
   135  
   136  	cb := func(c *Config) {
   137  		c.BootstrapExpect = 3
   138  		c.DevDisableBootstrap = true
   139  	}
   140  	s2 := testServer(t, cb)
   141  	defer s2.Shutdown()
   142  	s3 := testServer(t, cb)
   143  	defer s3.Shutdown()
   144  
   145  	testJoin(t, s1, s2, s3)
   146  	testutil.WaitForLeader(t, s2.RPC)
   147  	testutil.WaitForLeader(t, s3.RPC)
   148  
   149  	// s1 shouldn't be able to join
   150  	leader := ""
   151  	if err := s1.RPC("Status.Leader", &structs.GenericRequest{}, &leader); err == nil {
   152  		t.Errorf("expected a connection error from TLS server but received none; found leader: %q", leader)
   153  	}
   154  }
   155  
   156  func TestServer_Regions(t *testing.T) {
   157  	// Make the servers
   158  	s1 := testServer(t, func(c *Config) {
   159  		c.Region = "region1"
   160  	})
   161  	defer s1.Shutdown()
   162  
   163  	s2 := testServer(t, func(c *Config) {
   164  		c.Region = "region2"
   165  	})
   166  	defer s2.Shutdown()
   167  
   168  	// Join them together
   169  	s2Addr := fmt.Sprintf("127.0.0.1:%d",
   170  		s2.config.SerfConfig.MemberlistConfig.BindPort)
   171  	if n, err := s1.Join([]string{s2Addr}); err != nil || n != 1 {
   172  		t.Fatalf("Failed joining: %v (%d joined)", err, n)
   173  	}
   174  
   175  	// Try listing the regions
   176  	testutil.WaitForResult(func() (bool, error) {
   177  		out := s1.Regions()
   178  		if len(out) != 2 || out[0] != "region1" || out[1] != "region2" {
   179  			return false, fmt.Errorf("unexpected regions: %v", out)
   180  		}
   181  		return true, nil
   182  	}, func(err error) {
   183  		t.Fatalf("err: %v", err)
   184  	})
   185  }
   186  
   187  func TestServer_Reload_Vault(t *testing.T) {
   188  	s1 := testServer(t, func(c *Config) {
   189  		c.Region = "region1"
   190  	})
   191  	defer s1.Shutdown()
   192  
   193  	if s1.vault.Running() {
   194  		t.Fatalf("Vault client should not be running")
   195  	}
   196  
   197  	tr := true
   198  	config := s1.config
   199  	config.VaultConfig.Enabled = &tr
   200  	config.VaultConfig.Token = structs.GenerateUUID()
   201  
   202  	if err := s1.Reload(config); err != nil {
   203  		t.Fatalf("Reload failed: %v", err)
   204  	}
   205  
   206  	if !s1.vault.Running() {
   207  		t.Fatalf("Vault client should be running")
   208  	}
   209  }