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