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 }