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  }