github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/nomad/rpc_test.go (about) 1 package nomad 2 3 import ( 4 "net" 5 "net/rpc" 6 "os" 7 "path" 8 "testing" 9 "time" 10 11 msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc" 12 "github.com/hashicorp/nomad/nomad/mock" 13 "github.com/hashicorp/nomad/nomad/structs" 14 "github.com/hashicorp/nomad/nomad/structs/config" 15 "github.com/hashicorp/nomad/testutil" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 // rpcClient is a test helper method to return a ClientCodec to use to make rpc 20 // calls to the passed server. 21 func rpcClient(t *testing.T, s *Server) rpc.ClientCodec { 22 addr := s.config.RPCAddr 23 conn, err := net.DialTimeout("tcp", addr.String(), time.Second) 24 if err != nil { 25 t.Fatalf("err: %v", err) 26 } 27 // Write the Consul RPC byte to set the mode 28 conn.Write([]byte{byte(rpcNomad)}) 29 return NewClientCodec(conn) 30 } 31 32 func TestRPC_forwardLeader(t *testing.T) { 33 t.Parallel() 34 s1 := testServer(t, nil) 35 defer s1.Shutdown() 36 s2 := testServer(t, func(c *Config) { 37 c.DevDisableBootstrap = true 38 }) 39 defer s2.Shutdown() 40 testJoin(t, s1, s2) 41 testutil.WaitForLeader(t, s1.RPC) 42 testutil.WaitForLeader(t, s2.RPC) 43 44 isLeader, remote := s1.getLeader() 45 if !isLeader && remote == nil { 46 t.Fatalf("missing leader") 47 } 48 49 if remote != nil { 50 var out struct{} 51 err := s1.forwardLeader(remote, "Status.Ping", struct{}{}, &out) 52 if err != nil { 53 t.Fatalf("err: %v", err) 54 } 55 } 56 57 isLeader, remote = s2.getLeader() 58 if !isLeader && remote == nil { 59 t.Fatalf("missing leader") 60 } 61 62 if remote != nil { 63 var out struct{} 64 err := s2.forwardLeader(remote, "Status.Ping", struct{}{}, &out) 65 if err != nil { 66 t.Fatalf("err: %v", err) 67 } 68 } 69 } 70 71 func TestRPC_forwardRegion(t *testing.T) { 72 t.Parallel() 73 s1 := testServer(t, nil) 74 defer s1.Shutdown() 75 s2 := testServer(t, func(c *Config) { 76 c.Region = "region2" 77 }) 78 defer s2.Shutdown() 79 testJoin(t, s1, s2) 80 testutil.WaitForLeader(t, s1.RPC) 81 testutil.WaitForLeader(t, s2.RPC) 82 83 var out struct{} 84 err := s1.forwardRegion("region2", "Status.Ping", struct{}{}, &out) 85 if err != nil { 86 t.Fatalf("err: %v", err) 87 } 88 89 err = s2.forwardRegion("global", "Status.Ping", struct{}{}, &out) 90 if err != nil { 91 t.Fatalf("err: %v", err) 92 } 93 } 94 95 func TestRPC_PlaintextRPCSucceedsWhenInUpgradeMode(t *testing.T) { 96 t.Parallel() 97 assert := assert.New(t) 98 99 const ( 100 cafile = "../helper/tlsutil/testdata/ca.pem" 101 foocert = "../helper/tlsutil/testdata/nomad-foo.pem" 102 fookey = "../helper/tlsutil/testdata/nomad-foo-key.pem" 103 ) 104 dir := tmpDir(t) 105 defer os.RemoveAll(dir) 106 107 s1 := testServer(t, func(c *Config) { 108 c.DataDir = path.Join(dir, "node1") 109 c.TLSConfig = &config.TLSConfig{ 110 EnableRPC: true, 111 VerifyServerHostname: true, 112 CAFile: cafile, 113 CertFile: foocert, 114 KeyFile: fookey, 115 RPCUpgradeMode: true, 116 } 117 }) 118 defer s1.Shutdown() 119 120 codec := rpcClient(t, s1) 121 122 // Create the register request 123 node := mock.Node() 124 req := &structs.NodeRegisterRequest{ 125 Node: node, 126 WriteRequest: structs.WriteRequest{Region: "global"}, 127 } 128 129 var resp structs.GenericResponse 130 err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp) 131 assert.Nil(err) 132 133 // Check that heartbeatTimers has the heartbeat ID 134 _, ok := s1.heartbeatTimers[node.ID] 135 assert.True(ok) 136 } 137 138 func TestRPC_PlaintextRPCFailsWhenNotInUpgradeMode(t *testing.T) { 139 t.Parallel() 140 assert := assert.New(t) 141 142 const ( 143 cafile = "../helper/tlsutil/testdata/ca.pem" 144 foocert = "../helper/tlsutil/testdata/nomad-foo.pem" 145 fookey = "../helper/tlsutil/testdata/nomad-foo-key.pem" 146 ) 147 dir := tmpDir(t) 148 defer os.RemoveAll(dir) 149 150 s1 := testServer(t, func(c *Config) { 151 c.DataDir = path.Join(dir, "node1") 152 c.TLSConfig = &config.TLSConfig{ 153 EnableRPC: true, 154 VerifyServerHostname: true, 155 CAFile: cafile, 156 CertFile: foocert, 157 KeyFile: fookey, 158 } 159 }) 160 defer s1.Shutdown() 161 162 codec := rpcClient(t, s1) 163 164 node := mock.Node() 165 req := &structs.NodeRegisterRequest{ 166 Node: node, 167 WriteRequest: structs.WriteRequest{Region: "global"}, 168 } 169 170 var resp structs.GenericResponse 171 err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp) 172 assert.NotNil(err) 173 }