github.com/bigcommerce/nomad@v0.9.3-bc/nomad/client_rpc_test.go (about) 1 package nomad 2 3 import ( 4 "net" 5 "testing" 6 7 "github.com/hashicorp/nomad/client" 8 "github.com/hashicorp/nomad/client/config" 9 "github.com/hashicorp/nomad/helper/uuid" 10 "github.com/hashicorp/nomad/nomad/structs" 11 "github.com/hashicorp/nomad/testutil" 12 "github.com/stretchr/testify/require" 13 ) 14 15 type namedConnWrapper struct { 16 net.Conn 17 name string 18 } 19 20 type namedAddr string 21 22 func (n namedAddr) String() string { return string(n) } 23 func (n namedAddr) Network() string { return string(n) } 24 25 func (n namedConnWrapper) LocalAddr() net.Addr { 26 return namedAddr(n.name) 27 } 28 29 func TestServer_removeNodeConn_differentAddrs(t *testing.T) { 30 t.Parallel() 31 require := require.New(t) 32 s1 := TestServer(t, nil) 33 defer s1.Shutdown() 34 testutil.WaitForLeader(t, s1.RPC) 35 36 p1, p2 := net.Pipe() 37 w1 := namedConnWrapper{ 38 Conn: p1, 39 name: "a", 40 } 41 w2 := namedConnWrapper{ 42 Conn: p2, 43 name: "b", 44 } 45 46 // Add the connections 47 nodeID := uuid.Generate() 48 ctx1 := &RPCContext{ 49 Conn: w1, 50 NodeID: nodeID, 51 } 52 ctx2 := &RPCContext{ 53 Conn: w2, 54 NodeID: nodeID, 55 } 56 57 s1.addNodeConn(ctx1) 58 s1.addNodeConn(ctx2) 59 require.Len(s1.connectedNodes(), 1) 60 require.Len(s1.nodeConns[nodeID], 2) 61 62 // Check that the value is the second conn. 63 state, ok := s1.getNodeConn(nodeID) 64 require.True(ok) 65 require.Equal(state.Ctx.Conn.LocalAddr().String(), w2.name) 66 67 // Delete the first 68 s1.removeNodeConn(ctx1) 69 require.Len(s1.connectedNodes(), 1) 70 require.Len(s1.nodeConns[nodeID], 1) 71 72 // Check that the value is the second conn. 73 state, ok = s1.getNodeConn(nodeID) 74 require.True(ok) 75 require.Equal(state.Ctx.Conn.LocalAddr().String(), w2.name) 76 77 // Delete the second 78 s1.removeNodeConn(ctx2) 79 require.Len(s1.connectedNodes(), 0) 80 81 _, ok = s1.getNodeConn(nodeID) 82 require.False(ok) 83 } 84 85 func TestServerWithNodeConn_NoPath(t *testing.T) { 86 t.Parallel() 87 require := require.New(t) 88 s1 := TestServer(t, nil) 89 defer s1.Shutdown() 90 s2 := TestServer(t, func(c *Config) { 91 c.DevDisableBootstrap = true 92 }) 93 defer s2.Shutdown() 94 TestJoin(t, s1, s2) 95 testutil.WaitForLeader(t, s1.RPC) 96 testutil.WaitForLeader(t, s2.RPC) 97 98 nodeID := uuid.Generate() 99 srv, err := s1.serverWithNodeConn(nodeID, s1.Region()) 100 require.Nil(srv) 101 require.EqualError(err, structs.ErrNoNodeConn.Error()) 102 } 103 104 func TestServerWithNodeConn_NoPath_Region(t *testing.T) { 105 t.Parallel() 106 require := require.New(t) 107 s1 := TestServer(t, nil) 108 defer s1.Shutdown() 109 testutil.WaitForLeader(t, s1.RPC) 110 111 nodeID := uuid.Generate() 112 srv, err := s1.serverWithNodeConn(nodeID, "fake-region") 113 require.Nil(srv) 114 require.EqualError(err, structs.ErrNoRegionPath.Error()) 115 } 116 117 func TestServerWithNodeConn_Path(t *testing.T) { 118 t.Parallel() 119 require := require.New(t) 120 s1 := TestServer(t, nil) 121 defer s1.Shutdown() 122 s2 := TestServer(t, func(c *Config) { 123 c.DevDisableBootstrap = true 124 }) 125 defer s2.Shutdown() 126 TestJoin(t, s1, s2) 127 testutil.WaitForLeader(t, s1.RPC) 128 testutil.WaitForLeader(t, s2.RPC) 129 130 // Create a fake connection for the node on server 2 131 nodeID := uuid.Generate() 132 s2.addNodeConn(&RPCContext{ 133 NodeID: nodeID, 134 }) 135 136 srv, err := s1.serverWithNodeConn(nodeID, s1.Region()) 137 require.NotNil(srv) 138 require.Equal(srv.Addr.String(), s2.config.RPCAddr.String()) 139 require.Nil(err) 140 } 141 142 func TestServerWithNodeConn_Path_Region(t *testing.T) { 143 t.Parallel() 144 require := require.New(t) 145 s1 := TestServer(t, nil) 146 defer s1.Shutdown() 147 s2 := TestServer(t, func(c *Config) { 148 c.Region = "two" 149 }) 150 defer s2.Shutdown() 151 TestJoin(t, s1, s2) 152 testutil.WaitForLeader(t, s1.RPC) 153 testutil.WaitForLeader(t, s2.RPC) 154 155 // Create a fake connection for the node on server 2 156 nodeID := uuid.Generate() 157 s2.addNodeConn(&RPCContext{ 158 NodeID: nodeID, 159 }) 160 161 srv, err := s1.serverWithNodeConn(nodeID, s2.Region()) 162 require.NotNil(srv) 163 require.Equal(srv.Addr.String(), s2.config.RPCAddr.String()) 164 require.Nil(err) 165 } 166 167 func TestServerWithNodeConn_Path_Newest(t *testing.T) { 168 t.Parallel() 169 require := require.New(t) 170 s1 := TestServer(t, nil) 171 defer s1.Shutdown() 172 s2 := TestServer(t, func(c *Config) { 173 c.DevDisableBootstrap = true 174 }) 175 defer s2.Shutdown() 176 s3 := TestServer(t, func(c *Config) { 177 c.DevDisableBootstrap = true 178 }) 179 defer s3.Shutdown() 180 TestJoin(t, s1, s2, s3) 181 testutil.WaitForLeader(t, s1.RPC) 182 testutil.WaitForLeader(t, s2.RPC) 183 testutil.WaitForLeader(t, s3.RPC) 184 185 // Create a fake connection for the node on server 2 and 3 186 nodeID := uuid.Generate() 187 s2.addNodeConn(&RPCContext{ 188 NodeID: nodeID, 189 }) 190 s3.addNodeConn(&RPCContext{ 191 NodeID: nodeID, 192 }) 193 194 srv, err := s1.serverWithNodeConn(nodeID, s1.Region()) 195 require.NotNil(srv) 196 require.Equal(srv.Addr.String(), s3.config.RPCAddr.String()) 197 require.Nil(err) 198 } 199 200 func TestServerWithNodeConn_PathAndErr(t *testing.T) { 201 t.Parallel() 202 require := require.New(t) 203 s1 := TestServer(t, nil) 204 defer s1.Shutdown() 205 s2 := TestServer(t, func(c *Config) { 206 c.DevDisableBootstrap = true 207 }) 208 defer s2.Shutdown() 209 s3 := TestServer(t, func(c *Config) { 210 c.DevDisableBootstrap = true 211 }) 212 defer s3.Shutdown() 213 TestJoin(t, s1, s2, s3) 214 testutil.WaitForLeader(t, s1.RPC) 215 testutil.WaitForLeader(t, s2.RPC) 216 testutil.WaitForLeader(t, s3.RPC) 217 218 // Create a fake connection for the node on server 2 219 nodeID := uuid.Generate() 220 s2.addNodeConn(&RPCContext{ 221 NodeID: nodeID, 222 }) 223 224 // Shutdown the RPC layer for server 3 225 s3.rpcListener.Close() 226 227 srv, err := s1.serverWithNodeConn(nodeID, s1.Region()) 228 require.NotNil(srv) 229 require.Equal(srv.Addr.String(), s2.config.RPCAddr.String()) 230 require.Nil(err) 231 } 232 233 func TestServerWithNodeConn_NoPathAndErr(t *testing.T) { 234 t.Parallel() 235 require := require.New(t) 236 s1 := TestServer(t, nil) 237 defer s1.Shutdown() 238 s2 := TestServer(t, func(c *Config) { 239 c.DevDisableBootstrap = true 240 }) 241 defer s2.Shutdown() 242 s3 := TestServer(t, func(c *Config) { 243 c.DevDisableBootstrap = true 244 }) 245 defer s3.Shutdown() 246 TestJoin(t, s1, s2, s3) 247 testutil.WaitForLeader(t, s1.RPC) 248 testutil.WaitForLeader(t, s2.RPC) 249 testutil.WaitForLeader(t, s3.RPC) 250 251 // Shutdown the RPC layer for server 3 252 s3.rpcListener.Close() 253 254 srv, err := s1.serverWithNodeConn(uuid.Generate(), s1.Region()) 255 require.Nil(srv) 256 require.NotNil(err) 257 require.Contains(err.Error(), "failed querying") 258 } 259 260 func TestNodeStreamingRpc_badEndpoint(t *testing.T) { 261 t.Parallel() 262 require := require.New(t) 263 s1 := TestServer(t, nil) 264 defer s1.Shutdown() 265 testutil.WaitForLeader(t, s1.RPC) 266 267 c, cleanup := client.TestClient(t, func(c *config.Config) { 268 c.Servers = []string{s1.config.RPCAddr.String()} 269 }) 270 defer cleanup() 271 272 // Wait for the client to connect 273 testutil.WaitForResult(func() (bool, error) { 274 nodes := s1.connectedNodes() 275 return len(nodes) == 1, nil 276 }, func(err error) { 277 t.Fatalf("should have a clients") 278 }) 279 280 state, ok := s1.getNodeConn(c.NodeID()) 281 require.True(ok) 282 283 conn, err := NodeStreamingRpc(state.Session, "Bogus") 284 require.Nil(conn) 285 require.NotNil(err) 286 require.Contains(err.Error(), "Bogus") 287 require.True(structs.IsErrUnknownMethod(err)) 288 }